views:

79

answers:

3

Hi, can someone help me look at this. Getting too tired.

class User
  has_many :questions
  has_many :choices
end

class Question
  belongs_to :user
  has_many :answers
  has_one :choice, :through => :answer
end

class Answer
  belongs_to :question
end

class Choice
  belongs_to :user
  belongs_to :answer
  belongs_to :question, :through => :answer

  validates_uniqueness_of :answer_id, :scope => [ :question_id, :user_id ]
end

I am getting a NameError uninitialized constant User::Choice when I try to do current_user.choices

It works fine, if I don't include the

belongs_to :question, :through => :answer

But I want to use that because I want to be able to do the validates_uniqueness_of

I am probably overlooking something simple. Any help would be appreciated. Thanks!

A: 

The has_many :choices creates an association named choices, not choice. Try using current_user.choices instead.

See the ActiveRecord::Associations documentation for information about about the has_many magic.

Michael Melanson
Thanks for your help Michael, however, thats a typo on my part. I am already doing current_user.choices. This error has something to do with me wanting to assign belongs_to to user and question.
vinhboy
A: 

A belongs_to association cannot have a :through option. You're better off caching the question_id on Choice and adding a unique index to the table (especially because validates_uniqueness_of is prone to race conditions).

If you're paranoid, add a custom validation to Choice that confirms that the answer's question_id matches, but it sounds like the end user should never be given the opportunity to submit data that would create this kind of mismatch.

stephencelis
Thanks Stephen, I really didn't want to have to associate directly with question_id, but I guess its the easiest way.My original thought was, since "answer" belongs to "question", I can always go through "answer" to get to the "question". But do you think thats not easy to do, or do you think thats just a bad schema?
vinhboy
If you want a unique constraint/validations, the scoped fields must exist in the same table. Remember, there are race conditions.
stephencelis
A: 

It sounds like what you want is a User who has many Questions.
The Question has many Answers, one of which is the User's Choice.

Is this what you are after?

I would model something like that along these lines:

class User
  has_many :questions
end

class Question
  belongs_to :user
  has_many   :answers
  has_one    :choice, :class_name => "Answer"

  validates_inclusion_of :choice, :in => lambda { answers }
end

class Answer
  belongs_to :question
end
Adam Tanner