I wrote an upsert method for one of my models. I would like all my models to have this upsert method. It seemed to me that the logical solution was to define a model that inherits from ActiveRecord::Base
and then have all my other models inherit from that. But if I do that, Rails complains that the new model I created doesn't have a table to go with it, which is true, but I don't care.
我为我的一个模型写了一个upsert方法。我希望我的所有模型都有这种upsert方法。在我看来,逻辑解决方案是定义一个继承自ActiveRecord :: Base的模型,然后让我所有其他模型继承。但是,如果我这样做,Rails抱怨我创建的新模型没有表可以使用它,这是真的,但我不在乎。
Since the way I tried is apparently not the right way to do it, what's the right way to do it?
既然我尝试的方式显然不是正确的方法,那么正确的方法是什么?
3 个解决方案
#1
6
You can extend ActiveRecord with a module. you only do it in one place and it will be accessible for all models that inherits from ActiveRecord.
您可以使用模块扩展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
#2
3
There are two ways to do this.
有两种方法可以做到这一点。
1) To have a parent model, but not need to create a table for it (i.e. an abstract class) you should set
1)要有一个父模型,但不需要为它创建一个表(即一个抽象类),你应该设置它
class YourAbstractClass < ActiveRecord::Base
self.abstract_class = true
# rest of class code
end
2) Put the method in a module, that you include from all your models that need it (as in @Mark's answer)
2)将方法放在一个模块中,包含所有需要它的模型(如@ Mark的答案)
#3
0
You can move that method to a module and include that module in all the models that require that method.
您可以将该方法移动到模块,并将该模块包含在需要该方法的所有模型中。
Like I have this Utils module in lib folder of my app module Utils ...
就像我在我的应用程序模块Utils的lib文件夹中有这个Utils模块...
def to_name(ref)
ref.gsub('_', ' ').split.collect { |w| w.capitalize }.join(' ')
end
...
end
Then in my model, I say
然后在我的模型中,我说
class MyModel < AR::Base
include Utils
...
end
Probably, if you are using Rails 3, you should load the files in the lib folder by configuring your application.rb
可能,如果您使用的是Rails 3,则应通过配置application.rb来加载lib文件夹中的文件
config.autoload_paths += %W(#{config.root}/lib)
#1
6
You can extend ActiveRecord with a module. you only do it in one place and it will be accessible for all models that inherits from ActiveRecord.
您可以使用模块扩展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
#2
3
There are two ways to do this.
有两种方法可以做到这一点。
1) To have a parent model, but not need to create a table for it (i.e. an abstract class) you should set
1)要有一个父模型,但不需要为它创建一个表(即一个抽象类),你应该设置它
class YourAbstractClass < ActiveRecord::Base
self.abstract_class = true
# rest of class code
end
2) Put the method in a module, that you include from all your models that need it (as in @Mark's answer)
2)将方法放在一个模块中,包含所有需要它的模型(如@ Mark的答案)
#3
0
You can move that method to a module and include that module in all the models that require that method.
您可以将该方法移动到模块,并将该模块包含在需要该方法的所有模型中。
Like I have this Utils module in lib folder of my app module Utils ...
就像我在我的应用程序模块Utils的lib文件夹中有这个Utils模块...
def to_name(ref)
ref.gsub('_', ' ').split.collect { |w| w.capitalize }.join(' ')
end
...
end
Then in my model, I say
然后在我的模型中,我说
class MyModel < AR::Base
include Utils
...
end
Probably, if you are using Rails 3, you should load the files in the lib folder by configuring your application.rb
可能,如果您使用的是Rails 3,则应通过配置application.rb来加载lib文件夹中的文件
config.autoload_paths += %W(#{config.root}/lib)