belongs_to通过协会

鉴于以下关联,我需要引用Choice模型中的Choice 。 我一直试图使用belongs_to :question, through: :answer来执行这个动作。

 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 

我正进入(状态

NameError未初始化的常量User::Choice

当我尝试做current_user.choices

它工作正常,如果我不包括

 belongs_to :question, :through => :answer 

但我想使用它,因为我想能够做validates_uniqueness_of

我可能忽略了一些简单的事情。 任何帮助,将不胜感激。

belongs_to关联不能有:through选项。 你最好在Choice上cachingquestion_id并在表中添加一个唯一的索引(特别是因为validates_uniqueness_of容易出现竞争条件)。

如果你是偏执的,那么为Choice添加一个自定义validation,确认答案的question_id匹配,但是听起来像最终用户不应该有机会提交会产生这种不匹配的数据。

你也可以委托:

 class Company < ActiveRecord::Base has_many :employees has_many :dogs, :through => :employees end class Employee < ActiveRescord::Base belongs_to :company has_many :dogs end class Dog < ActiveRecord::Base belongs_to :employee delegate :company, :to => :employee, :allow_nil => true end 

只需要使用has_one而不是belongs_to :though ,像这样:

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

不相关,但我会犹豫是否使用validates_uniqueness_of,而不是在您的数据库中使用适当的唯一约束。 当你用ruby来做这件事时,你会遇到竞争状况。

您可以简单地使用has_one来代替belongs_to

 has_one :question, :through => :answer 

我的做法是做一个虚拟的属性,而不是添加数据库列。

 class Choice belongs_to :user belongs_to :answer # ------- Helpers ------- def question answer.question end # extra sugar def question_id answer.question_id end end 

这种方法非常简单,但是需要权衡。 它需要Rails从数据库加载answer ,然后question 。 稍后可以通过加载所需的关联(即c = Choice.first(include: {answer: :question}) )来优化,但是,如果此优化是必要的,那么stephencelis的答案可能是一个更好的性能决定。

有一些select的时间和地点,我认为这个select在原型devise时更好。 除非我知道这是一个不经常使用的情况,否则我不会将它用于生产代码。

这听起来像你想要的是一个有很多问题的用户。
这个问题有很多答案,其中之一就是用户的select。

这是你以后?

我会沿着这样的方式模拟这样的事情:

 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 

所以你不能有你想要的行为,但你可以做一些感觉就像。 你想能够做Choice.first.question

过去我所做的是这样的

 class Choice belongs_to :user belongs_to :answer validates_uniqueness_of :answer_id, :scope => [ :question_id, :user_id ] ... def question answer.question end end 

这样你现在可以在Choice上调用问题了

has_many :choices会创build一个名为choices的关联,而不是choice 。 尝试使用current_user.choices

有关has_many魔法的信息,请参阅ActiveRecord :: Associations文档。