2011-01-20 82 views
0

我为我的一个模型写了一个upsert方法。我希望我的所有模型都有这个upsert方法。在我看来,合乎逻辑的解决方案是定义一个从ActiveRecord::Base继承的模型,然后让我的所有其他模型从中继承。但如果我这样做,Rails抱怨说我创建的新模型没有一个表格,这是事实,但我不在乎。使所有的Rails模型都继承自某个类

因为我试过的方式显然不这样做的正确的方式,什么是做正确的方式?

回答

6

您可以使用模块来扩展ActiveRecord。你只能在一个地方做到这一点,所有从ActiveRecord继承的模型都可以访问它。

module YourModule 
    def self.included(recipient) 
    recipient.extend(ModelClassMethods) 
    recipient.class_eval do 
     include ModelInstanceMethods 
    end 
    end # #included directives 

    # Class Methods 
    module ModelClassMethods 
    # A method accessible on model classes 
    def whatever 

    end 
    end 

    # Instance Methods 
    module ModelInstanceMethods 
    #A method accessible on model instances 
    def another_one 

    end 
    end 
end 

#This is where your module is being included into ActiveRecord 
if Object.const_defined?("ActiveRecord") 
    ActiveRecord::Base.send(:include, YourModule) 
end 
+0

哇!这看起来很酷。我还没有尝试过,但肯定是有效的! +1为此从我。 – 2011-01-20 16:03:53

3

有两种方法可以做到这一点。

1)有一个父模型,而不是需要创建一个表,它(即抽象类),你应该设置

class YourAbstractClass < ActiveRecord::Base 
    self.abstract_class = true 

    # rest of class code 
end 

2)把该方法在module,你从包括所有模型需要它(如@马克的回答)

0

您可以在方法移动到一个模块,包括在需要该方法的所有型号的模块。

像我这个utils的模块在我的应用 模块utils的 的lib文件夹...

def to_name(ref) 
     ref.gsub('_', ' ').split.collect { |w| w.capitalize }.join(' ') 
    end 

    ... 
end 
在我的模型

然后,我说

class MyModel < AR::Base 
    include Utils 
    ... 
end 

也许,如果你正在使用Rails 3,你应该通过配置你的应用程序来加载lib文件夹中的文件.rb

config.autoload_paths += %W(#{config.root}/lib)