簡體   English   中英

通過關聯belongs_to

[英]belongs_to through associations

鑒於以下關聯,我需要從Choice模型中引用Choice附加的Question 我一直在嘗試使用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

我可能忽略了一些簡單的事情。 任何幫助,將不勝感激。

您還可以委托:

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

只需在您的:through使用has_one而不是belongs_to ,就像這樣:

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

不相關,但我會猶豫是否使用 validates_uniqueness_of 而不是在您的數據庫中使用適當的唯一約束。 當您在 ruby​​ 中執行此操作時,您會遇到競爭條件。

一個belongs_to關聯不能有一個:through選項。 您最好在Choice上緩存question_id並向表中添加唯一索引(特別是因為validates_uniqueness_of容易出現競爭條件)。

如果您是偏執狂,請向Choice添加自定義驗證以確認答案的question_id匹配,但聽起來最終用戶永遠不應有機會提交會造成這種不匹配的數據。

我的方法是創建一個虛擬屬性而不是添加數據庫列。

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 的答案可能是更好的性能決策。

某些選擇是有時間和地點的,我認為在原型設計時這種選擇更好。 除非我知道它用於不常見的用例,否則我不會將它用於生產代碼。

所以你不能有你想要的行為,但你可以做一些感覺像它的事情。 你希望能夠做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

這樣你現在可以在選擇上提出問題

聽起來您想要的是一個有很多問題的用戶。
問題有許多答案,其中之一是用戶的選擇。

這是你追求的嗎?

我會沿着這些路線建模類似的東西:

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

has_many :choices創建一個協會命名choices ,而不是choice 嘗試使用current_user.choices代替。

有關has_many魔法的信息,請參閱ActiveRecord::Associations文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM