2009-07-15 59 views
1

我有一个基本的has_many:通过关系是双向的:bulk has_many的默认代码是什么:通过在rails中的连接赋值?

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:通过设置,但是,我想重写这个函数来添加一些额外的魔法。我查看了rails的源代码,找不到这个函数的代码。我想知道是否有人可以指给我。然后我会重写它为该类补充一点,我想要的东西:)

回答

2

您可以在行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 

你一定要避免这样的重写这个方法来增加魔法的东西找到文件lib/active_record/associations.rb的源代码。有时候Rails已经“太神奇了”。我建议创建所有自定义逻辑虚拟属性有以下几个原因:

  1. 其他一些轨道的方法可能依赖默认的实现
  2. 你依靠,可能会在未来的ActiveRecord更改特定API版本
+0

这是一个很好的观点。在我的示例中,我刚刚在我的事件模型中覆盖了日历=方法。这还不好吗?是否有可能链接这些方法?我从来没有做过,但我已经看到了一点。我想要做的就是在必要的情况下将一个额外事件添加到日历=参数上的new_value事件数组中。 – 2009-07-15 22:47:33

0

作为对上述答案的回应,我使用alias_method_chain来覆盖默认设置器并添加我的特性。工作得很好,但我不知道为什么我必须发送方法setter,而不是正常使用它。它似乎没有工作,虽然所以这会做:)

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