1

我有一个基本的 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 源代码,找不到该函数的代码。我想知道是否有人可以指出我。然后我将为这个类覆盖它以添加我想要的东西:)

4

3 回答 3

2

经过一番寻找,我找到了它:

http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/collection_accessor_methods

它看起来不像我想象的那样,所以这就是为什么我可能错过了它。我最终覆盖了 calendars= 方法而不是 calendar_ids= 方法,并且一切正常。

于 2009-07-15T11:09:36.863 回答
2

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. 您依赖的特定 API 可能会在未来的 ActiveRecord 版本中发生变化
于 2009-07-15T11:18:24.803 回答
0

针对上面的答案,我使用 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
于 2009-07-15T23:23:08.797 回答