Rails での一括 has_many :through join 割り当てのデフォルトのコードは何ですか?
-
16-09-2019 - |
質問
双方向の基本的な has_many :through 関係があります。
calendars have many calendar_calendar_events
calendars have many events through calendar_calendar_events
events have many calendar_calendar_events
events have many calendars through calendar_calendar_events
基本的な設定でカレンダーをイベントに割り当てたいと考えています。 calendar_ids=
has_many :through が設定する関数ですが、この関数をオーバーライドして追加の魔法を追加したいと考えています。Rails ソースを調べましたが、この関数のコードが見つかりません。誰かが私にそれを教えてくれないかと思います。次に、このクラスのそれをオーバーライドして、必要なものを追加します:)
解決
ファイル内のソースコードを見つけることができます lib/active_record/associations.rb
1295行目
def collection_accessor_methods(reflection, association_proxy_class, writer = true)
collection_reader_method(reflection, association_proxy_class)
if writer
define_method("#{reflection.name}=") do |new_value|
# Loads proxy class instance (defined in collection_reader_method) if not already loaded
association = send(reflection.name)
association.replace(new_value)
association
end
define_method("#{reflection.name.to_s.singularize}_ids=") do |new_value|
ids = (new_value || []).reject { |nid| nid.blank? }
send("#{reflection.name}=", reflection.class_name.constantize.find(ids))
end
end
end
このようなメソッドを上書きして魔法のものを追加することは絶対に避けるべきです。Rails はすでに「魔法が多すぎる」場合があります。いくつかの理由から、すべてのカスタム ロジックを含む仮想属性を作成することをお勧めします。
- 他のいくつかの Rails メソッドはデフォルトの実装に依存する可能性があります
- 将来の ActiveRecord バージョンで変更される可能性がある特定の API に依存している
他のヒント
狩りのビットの後、私はそれを見つけます:
http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/collection_accessor_methods の
これは、私はおそらくそれを逃した理由ですので、それは、ように見えるだろうと思ったもののように見えませんでした。私はcalendar_ids =メソッドの代わりにカレンダー=メソッドをオーバーライドしてしまったし、すべてがうまく動作します。
は、上記の回答を受けて、私はデフォルトのセッターをオーバーライドして、私の機能を追加するために使用さalias_method_chain。私はちょうど正常にそれを使用するのではなく、メソッドのセッターを送信するために持っている理由はわからないものの、非常によく動作します。ので、これは何でしょうが、それが動作していないようでした:)
def calendars_with_primary_calendar=(new_calendars)
new_calendars << calendar unless new_record?
send('calendars_without_primary_calendar=', new_calendars) # Not sure why we have to call it this way
end
alias_method_chain :calendars=, :primary_calendar