2017-08-16 54 views
0

私はSelectionモデルが多く、Choicesと1つはDefaultChoiceです。 このように関係が構成されています。has_oneの関係から予期せぬ結果を得る

モデル(私は間違って何かがあり、ここだと思う)

class Selection < ApplicationRecord 
    has_many :choices, dependent: :delete_all 
    has_one :default_choice, class_name: 'Choice' 
end 

class Choice < ApplicationRecord 
    belongs_to Selection 
end 

移行

create_table :selections do |t| 
    t.references :default_choice, index: true 
end 
create_table :choices do |t| 
    t.belongs_to :selection 
end 

どういうわけか何かが右ではありません。

# let's say: 
selection = Selection.find(1) 
selection.choices << Choice.find(1) 
selection.choices << Choice.find(2) 
selection.default_choice = Choice.find(2) 
selection.save! 

# then 
selection.default_choice_id = 2 
# but 
selection.default_choice.id = 1 

来る方法!

selection.default_choiceは、このクエリを生成します。

Choice Load (0.5ms) SELECT "choices".* FROM "choices" WHERE "choices"."selection_id" = $1 LIMIT $2 [["selection_id", 1], ["LIMIT", 1]] 
+0

基本的に 'selection.default_choice'は常に' selection.choices'の最初の選択肢を返します。 –

+0

'selection.default_choice'を実行したときに実行されるSQLクエリを投稿できます – Pavan

+0

SQLクエリを追加する質問が更新されました –

答えて

0

あなたは両方の関係has_many :choicheshas_one :default_choiceのために同じモデルChoiceを使用しています。したがって、has_one :default_choiceの結果を照会すると、すべてchoicesテーブルからなり、has_oneでは、選択オブジェクトを参照して最初に見つかった結果が1つだけ取得されます。


UPDATE

あなたはそれがデフォルトの選択です場合はtrueになります選択モデルに列を追加するような操作を行うことができますにhas_manyのデフォルトを実装します。そして、has_oneの関係は、このような真のデフォルトで唯一の選択肢を取得するスコープを持っている必要があります:

has_one :default_choice, -> { where default_choice: true }, class_name: 'Choice' 
+0

これは私にとっては明らかです。しかし、どうすれば特定の 'default_choice'を設定できますか? –

+0

これはあなたが尋ねたこと以外の全く別の質問です。 Choiceのadd columnのようなことができます。デフォルトの選択であれば 'true'になります。次に、has_one関係には、スコープを持たせて、デフォルトのtrueを選択します。 'has_one:default_choice、 - > {default_choice:true}、class_name: 'Choice'' – meshin

関連する問題