2011-01-26 58 views
1

我成功创建有一些类和模块be'ing能够以类似的东西在Rails项目任何一种类的宝石:了解创建acts_as_anything

class AnyRubyOrActiveModelClass 
    acts_as_anything [:foo, :bar] 

    def foo 
    .. do some foo 
    end 

    def self.bar 
    .. do some bar 
    end 
end 

要做到这一点我创建了一个模块在我的宝石看起来类似的东西:

module InstanceMagic 
    class << self.class.superclass 
    define_method(:acts_as_anything) do |methods| 
    self.class_eval do 
     include ClassMagic 
     .. do some alias_method with given methods 
    end 
    end 
end 

此模块成功化名我的方法:从上面的例子中富,第二模块ClassMagic她对我的一样:棒类方法,(从here的意见) 。

在testproject这种做法效果很不错。在一个真实的项目中,它导致了对另一个宝石的干涉 - 采用 - 也许类似 - 的方法。这个宝石抱怨即使我只把我的宝石融入到这个项目中,也没有在课堂上集成acts_as_anything,所以在课堂上缺少方法。

所以我我的代码崩溃了,只说:

module InstanceMagic 
    class << self.class.superclass 
    define_method(:acts_as_anything) do |methods| 
    #really empty here 
    end 
end 

其结果是其他宝石仍然打破。

我用类< < self.class.superclass来显式扩展Object,以便即使非ActiveSomething类但所有类都受到影响,并且我的acts_as_anything可用。所以我仍然有三个问题。

为什么最后5行代码打破另一颗宝石,并使其抱怨缺少它试图动态创建的方法呢?我想明白。

有没有更好的方法来实现我的目标?当我使用method_added和singleton_method_added(我在模块中实际做的事情)时,我应该查找这些方法,不管它们是否已经存在,别名为“原始”方法,插入我的方法并在完成后调用原始方法我的工作?

知道这是很多我还是希望有人能指出我到正确的方向。

谢谢。 菲利克斯

+0

你可以添加任何错误或至少冲突的宝石?为什么使用self.class.superclass?在模块上下文中的self.class.superclass将始终是Object,为什么不只是为了可读性而说呢?如果我能够获得有关错误的更多背景信息,我希望能提供帮助。 – shawn42 2011-01-31 04:48:15

+0

Shawn,谢谢你的建议。他们欢迎。抱怨工作的宝石是:friendly_id。如果我启动我的应用程序在控制台上,我得到以下错误: /Users/felix/.rvm/gems/[email protected]/gems/activerecord-2.3.10/lib/active_record/base .RB:1998:在`method_missing_without_paginate为# ':未定义的方法`has_friendly_id:NoMethodError'<类别:0x1059fc148> 红宝石1.8.7-P299>用户 用户列(2.9ms)显示字段FROM`users` NoMethodError: SQL(1.9ms)SHOW TABLES 未定义的方法`has_friendly_id”为#<类别:0x105d74438> – GeorgieF 2011-01-31 08:46:22

回答

0

唯一我能想到的事情是某种顺序的依存关系(长镜头)的。尝试将你的代码放入rails应用程序的初始化程序中,看看它是否仍然会导致相同的问题。