5

Google スプレッドシートを Rails モデルに変換できるようにする gem を作成しました。このプロセスの順序には、すべてのモデルの作成、それらの関連付けの接続、すべてのモデルの保存が含まれます。利用可能なすべてのタイプの関連付けをサポートし、いずれの場合でも、モデルの作成、関連付けの確立、およびモデルの保存が正しく機能します。例外は次のとおりです。

私は単純なhas_one, through関連付けを持っています(簡潔にするために属性アクセスは省略されています):

class Left < ActiveRecord::Base
   has_many :middles, dependent: :destroy
   has_many :rights, through: :middles
end

class Right < ActiveRecord::Base 
   has_one :middle, dependent: :destroy
   has_one :left, through: :middle
end

class Middle < ActiveRecord::Base
  belongs_to :left
  belongs_to :right
end

関連付けの割り当てがどちら側で行われるかによって、一貫性のない動作が見つかります。

右から左への割り当て:

left = Left.new
right = Right.new
left.rights << right
left.middles #[]
right.middle #nil
left.save!
left.middles # <Middle theme_id: 1, archive_resource_id: 1 >

右から左への割り当て:

left = Left.new
right = Right.new
right.left = left
left.middles #[]
right.middle <Middle theme_id: nil, archive_resource_id: nil >
right.save!
right.middle # <Middle theme_id: nil, archive_resource_id: 1 >

この動作は非常に矛盾しているようです。どうしてこれなの?なぜこれは一方の方法で機能し、もう一方の方法では機能しないのですか? 保存されていない両方のレコードでこの関係を確立する方法はありますか?

明らかな解決策は、関係を設定する前にすべてを保存することですが、上記で説明したように、関連付けが確立されたときにモデルを保存しない必要があり、他のすべてのタイプの関連付けでは、この点で問題はありません。

4

3 に答える 3

-1

おそらく機能していると思いますが、すぐには更新されません。true関連付けメソッドを呼び出すときに渡してみてください。元。right.middle(true). これにより、古いキャッシュをチェックする代わりに、Rails がデータベースに戻ってレコードを取得することが強制されます。ただし、メモリ内の関連付けられたオブジェクトを吹き飛ばしてしまうため、新しいレコードではこれを行わないでください。

リロードを強制する必要がないようにするinverse_ofには、関連付けを次のように設定します。

class Left < ActiveRecord::Base
   has_many :middles, dependent: :destroy, inverse_of: :left
   has_many :rights, through: :middles
end

class Right < ActiveRecord::Base 
   has_one :middle, dependent: :destroy, inverse_of: :right
   has_one :left, through: :middle
end

class Middle < ActiveRecord::Base
  belongs_to :left, inverse_of: :middles
  belongs_to :right, inverse_of: :middle
end

inverse_of関連付けられたモデルとそれ自体との関係をmodel認識し、関連付けられたオブジェクトの永続化と読み込みについて「スマート」にすることができます。

于 2013-11-05T06:00:12.650 に答える