views:

45

answers:

1

I was hoping someone would spot why this wouldn't work.

I am getting an error thats being called because the attributes I specify with Factory_Girl are not being applied to the stub before validation.

The Error:

undefined method `downcase' for #<Category:0x1056f2f60>

RSpec2

it "should vote up" do
  @mock_vote = Factory.create(:vote)
  Vote.stub(:get_vote).and_return(@mock_vote)
  get :vote_up, :id => "1"        
end

Factories

Factory.define :vote, :class => Vote do |v|
  v.user_id "1"
  v.association :post
end

Factory.define :post, :class => Post do |p|
  p.category "spirituality"
  p.name "sleezy snail potluck"
  p.association :category
end

Factory.define :category, :class => Category do |c|
  c.name "spirituality"
  c.id "37"
end

Post.rb - Model

before_save           :prepare_posts
validate              :category?

def prepare_posts
  self.update_attribute("category", self.category.downcase)
  if self.url?
    self.url = "http://" + self.url unless self.url.match /^(https?|ftp):\/\//
  end
end

def category?
  unless Category.exists?(:name => self.category.downcase)
    errors.add(:category, "There's no categories with that name.")
  end
  return true
end

Also, feel free to nitpick any blatantly gross looking code. :D

Thanks!!

+2  A: 

You have a category attribute, which appears to be a string, but you also seem to have a category association which automatically creates, among other things, an attribute on Post called category, probably overwriting your category attribute. Hence, the Category class has no downcase method, because it's not a String.

Rename your category attribute to something like category_name, but really you shouldn't have that attribute at all.

Maybe where you're calling self.category.downcase you meant self.category.name.downcase?

rspeicher
Just trying to wrap my brain around this. I think what you're saying is that the Post downcase method is being passed to its association as well because it has the same name as its attribute? And if I rename it then it would factory it without passing its through the Post model. Why would you suggest I not have that attribute at all?
Trip
`downcase` is an instance method of the String class. You're trying to call it on `self.category` which is a Category object (your model), which doesn't have that method because it's not a String. I'm not sure I understand the rest of your comment.
rspeicher
Ah but self.category is a string. Because users type in the categories of their posts, I needed to use a string value to relate their posts to categories. So Post has an attribute category. And if that string matches a Category.name, then they match in search results. But even though self.category is a string for Post, it **does** seem like its calling it as the Category model. To which I'm assuming is because the association name is the same name as the attribute?
Trip
If that's the case, then yes, my original answer stands. You have a category **attribute**, and a category **association**. The association is taking precedent and overwriting your attribute. Rename your attribute to category_name.
rspeicher
Hmm, changing the p.association to p.association :category, :factory => :valid_category doesn't seem to change the error. Even when I removed the p.category from the Post factory, and the validation for in the Category model. Maybe I'm not understanding association :D How does one label Post.category "Any String", and also with it create a Category via Factory.
Trip
I think I get it. Associations are used like relational models, ex: belongs_to etc. In this case, because my two models are connected by strings, it would be innapropriate for me to relate them by association. I should just stub two models in my rspec. On a side note, I can't thank you enough rspeicher. You've been an incredible help.
Trip