次の関連付けを考えると、Question
が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
オプションを含めることはできません。 question_id
をChoice
にキャッシュし、テーブルに一意のインデックスを追加することをお勧めします(特にvalidates_uniqueness_of
は競合状態になりやすいため)。
偏執的な場合は、Choice
にカスタム検証を追加して、回答の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でこれを行うと、競合状態になります。
私のアプローチは、データベース列を追加する代わりに仮想属性を作成することでした。
class Choice
belongs_to :user
belongs_to :answer
# ------- Helpers -------
def question
answer.question
end
# extra sugar
def question_id
answer.question_id
end
end
このアプローチは非常に単純ですが、トレードオフが伴います。データベースからanswer
をロードするにはRailsが必要で、次にquestion
が必要です。これは後で必要なアソシエーション(つまりc = Choice.first(include: {answer: :question})
)を積極的にロードすることで最適化できますが、この最適化が必要な場合は、おそらくステファンスリスの答えがパフォーマンスのより良い決定です。
特定の選択肢には時間と場所があり、プロトタイピングの際にはこの選択肢の方が良いと思います。使用頻度の低いユースケースであることがわからない限り、本番コードには使用しません。
だからあなたが望む行動をすることはできませんが、あなたはそれのように感じる何かをすることができます。 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で質問を呼び出すことができます
あなたが望むのは、多くの質問を持つユーザーであるように思えます。
質問には多くの回答があり、そのうちの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