我爲我的一個模型寫了一個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