views:

62

answers:

2

I have a Post class with a vote method which creates a Vote instance

This doesn't work

def vote(options)
   vote = self.votes.create(options)
   return vote if vote.valid?
   nil
end

This does work

def vote(options)
   options[:post] = self
   vote = self.votes.create(options)
   return vote if vote.valid?
   nil
end

Shouldn't the .create call automatically add the :post association?

CLARIFICATION

class Post < ActiveRecord::Base has_many :votes end

class Vote < ActiveRecord::Base belongs_to :user, :counter_cache => true belongs_to :post end

A: 

Do you have

has_many :votes

declared in your Post model?

At what point are you calling the vote method in the object's lifecycle? It it part of a callback method?

bensie
I call the vote method after the object has been created (and saved).The vote method call is not part of a callback.
Alexandre
If it didn't have has_many :votes than self.votes.create would have caused an error in both cases.
EmFi
@Alexandre If you're calling vote after the object has been created, why does it create a new one?
EmFi
@EmFi Sorry, I didn't understand your question. Which object has been created when a new one is created?
Alexandre
It may also be easier if you provided more model code and the commands that you're using to test in the console.
bensie
A: 

It would be easier to debug if you wrote it as self.votes.create!(options) because then it will throw an exception with an error message. You can take this out once you fix the problem, but you should think about what your method should return if it doesn't work.

Does it make sense for Post#vote to return nil? Why should casting a vote fail? How does your code handle the nil value returned by Post#vote?

Maybe you should just re-write it as:

def vote(options)
  self.votes.create!(options)
end
Luke Francl
It would return nil if a user had already voted, in which case the vote would be invalid.
Alexandre
OK. Did you try switching to create! to see what the error from ActiveRecord is?
Luke Francl