Rails での一括 has_many :through join 割り当てのデフォルトのコードは何ですか?

StackOverflow https://stackoverflow.com/questions/1130642

質問

双方向の基本的な 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 はすでに「魔法が多すぎる」場合があります。いくつかの理由から、すべてのカスタム ロジックを含む仮想属性を作成することをお勧めします。

  1. 他のいくつかの Rails メソッドはデフォルトの実装に依存する可能性があります
  2. 将来の 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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top