仅列出ActiveRecord子类方法

时间:2012-02-26 21:43:16

标签: ruby activerecord metaprogramming

给出以下ActiveRecord模型:

class User < ActiveRecord::Base
  has_many :games
  def name
    "Joe"
  end

  def city
     "Chicago"
  end
end

我想检索我直接添加到User类的方法列表(而不是通过扩展ActiveRecord和/或添加关联添加的方法)。示例输出:

["name","city"]

调用User.instance_methods(false)返回ActiveRecord添加的方法:

["validate_associated_records_for_games", "games", "game_ids", "games=", "game_ids=", "after_create_or_update_associated_records_for_games", "before_save_associated_records_for_games"]

以及数据库列中的任何模型属性。我想排除那些,只是在子类上获取自定义方法。

我的目的是方法跟踪:我想跟踪我的自定义方法,同时排除ActiveRecord添加的方法。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

User.instance_methods - ActiveRecord::Base.instance_methods #=> [:name,:city]

更新:

这些方法的顺序很重要

class User < ActiveRecord::Base
  def self.my_own_methods
    self.instance_methods - @@im
  end
  has_many :games
  @@im = self.instance_methods
  def name
    "Joe"
  end
  def city
    "Chicago"
  end
end

User.my_own_methods #=> [:name, :city]

这个测试过并且有效

答案 1 :(得分:0)

使用method_added挂钩将方法名称添加到列表中,并使用猴子补丁Active Record,以便AR添加的方法不会添加到该列表中。

如果您不想破解AR并开始探索,您还可以定义一个“类宏”,它定义一个方法并将添加到列表中。对于您自己的自定义方法,请使用类宏而不是def

如果你不熟悉我所说的“类宏”,它只是一个这样的方法:

class Class
  def mydef(name,&block)
    (@methods || []) << name
    define_method(name,&block)
  end
end

使用像mydef之类的东西来定义方法而不是def绝对是丑陋的,但它可以在不需要任何猴子修补的情况下解决问题。