鉴于以下关联,我需要引用从Question
模型附加Choice
的{{1}}。我一直在尝试使用Choice
来执行此操作。
belongs_to :question, through: :answer
我正在
NameError未初始化的常量
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
当我尝试User::Choice
如果我不包含
,它可以正常工作current_user.choices
但我想使用它,因为我希望能够执行belongs_to :question, :through => :answer
我可能忽略了一些简单的事情。任何帮助将不胜感激。
答案 0 :(得分:339)
您也可以委派:
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
答案 1 :(得分:94)
只需在has_one
中使用belongs_to
代替:though
,就像这样:
class Choice
belongs_to :user
belongs_to :answer
has_one :question, :through => :answer
end
不相关,但我会犹豫是否使用validates_uniqueness_of而不是在数据库中使用适当的唯一约束。当您在红宝石中执行此操作时,您会遇到竞争条件。
答案 2 :(得分:57)
belongs_to
关联不能有:through
选项。您最好在question_id
上缓存Choice
并为表添加唯一索引(特别是因为validates_uniqueness_of
容易出现竞争条件)。
如果你是偏执狂,请向Choice
添加一个自定义验证,确认答案的question_id
匹配,但听起来最终用户永远不应该有机会提交会创建的数据这种不匹配。
答案 3 :(得分:4)
我的方法是创建一个虚拟属性,而不是添加数据库列。
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从db加载answer
,然后question
。这可以通过急切加载您需要的关联(即c = Choice.first(include: {answer: :question})
)进行优化,但是,如果需要进行此优化,那么stephencelis的回答可能是更好的性能决策。
某些选择有时间和地点,我认为在原型设计时这种选择会更好。我不会将它用于生产代码,除非我知道它是用于不经常的用例。
答案 4 :(得分:1)
听起来你想要的是一个有很多问题的用户 该问题有很多答案,其中一个是用户选择。
这就是你追求的吗?
我会按照以下方式对此进行建模:
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
答案 5 :(得分:1)
所以你不能拥有你想要的行为,但你可以做一些感觉就像它的事情。您希望能够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
通过这种方式,您现在可以在选择
上调用问题答案 6 :(得分:-1)
has_many :choices
创建名为choices
的关联,而不是choice
。请尝试使用current_user.choices
。
有关has_many
魔术的详细信息,请参阅ActiveRecord::Associations文档。