如何在运行时向has_many关系添加方法

时间:2013-05-23 10:01:56

标签: ruby-on-rails activerecord

我正在尝试为be_many关系添加迟来的方法,我不想在构建时间(:has_many panties do ... end)中也不想这样做,也不想在某个范围内执行它(我希望它能够在每个has_many或者集合协会中工作。我已经尝试过了:

  1. 在ActiveRecord :: Associations :: CollectionAssociation类中包含方法
  2. 在ActiveRecord :: Associations :: CollectionProxy类中包含方法
  3. 似乎什么都没有用。我只能跟踪将未定义的方法传递给类,这不是我想要的。

    我想要的结果是:

    class Man < ActiveRecord::Base
      has_many :balls
    end
    
    class Woman < ActiveRecord::Base
      has_many :breasts
    end
    
    # magic to insert methods
    
    Man.new.balls.say_hi #=> "hi jerry"
    Woman.new.breasts.say_hi #=> "hi jerry"
    

    如此简单,却又如此困难。这种AR中方法的代理使得调试变得如此困难。

    编辑:

    我的目的不是插入更多业务逻辑,而是将集合添加到集合中,以便我提取有关集合的信息并在其他地方使用它。我再说一遍,这些信息与业务逻辑无关,而是与集合关联中“隐藏”的一些活动记录信息有关,比如知道哪个类是子节点,父节点中的关联名称等等。

    然后可以通过#composite_object之类的集合方法获得此复合对象,这将为我提供此信息。但我不知道如何在不重新定义关联的情况下插入此方法。

2 个答案:

答案 0 :(得分:0)

您需要为has_many定义一个围绕别名,该别名位于ActiveRecord::Associations::ClassMethods中,通过一个开放模块。

围绕别名只会调用旧的has_many方法,然后使用define_method添加say_hi

答案 1 :(得分:0)

您是否考虑过ActiveRecord :: QueryMethods #extended方法? http://apidock.com/rails/ActiveRecord/QueryMethods/extending

module Belatedly
  def say_hi
    "hi jerry"
  end
end

children = Child.all.extending Belatedly
children.say_hi

class Parent < ActiveRecord::Base
  has_many :children, -> { extending Belatedly }
end

Parent.first.children.say_hi