2012-02-26 47 views
1

鉴于以下ActiveRecord的模型:只列出的ActiveRecord子类的方法

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

    def city 
    "Chicago" 
    end 
end 

我想找回我直接添加到用户类中的方法列表(而不是那些通过扩展ActiveRecord的添加和/或添加关联)。示例输出:

["name","city"] 

调用User.instance_methods(假)返回方法,通过添加的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添加的方法。

任何想法?

+0

什么版本的轨道您使用的作品? – 2012-02-26 21:50:55

+0

我正在测试w/Rails 2.2.2,但我愿意接受更新版本的解决方案。 – 2012-02-26 22:21:59

+0

在rails 3.2中,属性访问器,关联访问器和可能的验证内容是在你的模型中包含的方法中定义的,这使得你试图做的更容易 – 2012-02-27 07:28:45

回答

0

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

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

如果你不熟悉的东西我指的是作为“阶级宏”,它只是一个像这样的方法:

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

使用类似mydef定义方法,而不是def绝对是丑陋,但它会解决问题,而不需要任何猴子修补。

+0

为了澄清,“类宏”是一个实例方法在'Class'上,你可以从'class'块中调用以定义方法等'attr_accessor'是另一个例子。 – 2012-02-26 21:58:13

+0

方法的参数呢? – megas 2012-02-26 22:03:08

+0

如果传递给'define_method'的块带有参数,则生成的方法也将带有参数。 – 2012-02-26 22:04:25

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

UPDATE:

这些方法的顺序是显著

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] 

这一个测试,它

+0

这不起作用,因为由AR自动生成的方法(例如用于数据库列的方法)不会在'ActiveRecord :: Base.instance_methods'中。 – 2012-02-26 22:12:18

+0

是的 - 这返回ActiveRecord添加到User类的方法。例如,你会看到类似':games ='的输出,这是我不想要的,但是因为'有许多:游戏'关联而被包括在内。 – 2012-02-26 22:27:54

+0

更新后,请参阅最新版本 – megas 2012-02-26 22:36:25

相关问题