使所有Rails模型继承自某个类

时间:2022-09-25 10:32:22

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)