我为我的一个模型写了一个upsert方法。我希望我的所有模型都有这个upsert方法。在我看来,合乎逻辑的解决方案是定义一个从ActiveRecord::Base
继承的模型,然后让我的所有其他模型从中继承。但如果我这样做,Rails抱怨说我创建的新模型没有一个表格,这是事实,但我不在乎。使所有的Rails模型都继承自某个类
因为我试过的方式显然不这样做的正确的方式,什么是做正确的方式?
我为我的一个模型写了一个upsert方法。我希望我的所有模型都有这个upsert方法。在我看来,合乎逻辑的解决方案是定义一个从ActiveRecord::Base
继承的模型,然后让我的所有其他模型从中继承。但如果我这样做,Rails抱怨说我创建的新模型没有一个表格,这是事实,但我不在乎。使所有的Rails模型都继承自某个类
因为我试过的方式显然不这样做的正确的方式,什么是做正确的方式?
您可以使用模块来扩展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
有两种方法可以做到这一点。
1)有一个父模型,而不是需要创建一个表,它(即抽象类),你应该设置
class YourAbstractClass < ActiveRecord::Base
self.abstract_class = true
# rest of class code
end
2)把该方法在module,你从包括所有模型需要它(如@马克的回答)
您可以在方法移动到一个模块,包括在需要该方法的所有型号的模块。
像我这个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)
哇!这看起来很酷。我还没有尝试过,但肯定是有效的! +1为此从我。 – 2011-01-20 16:03:53