Ruby on rails 使所有Rails模型从特定类继承

Ruby on rails 使所有Rails模型从特定类继承,ruby-on-rails,Ruby On Rails,我为我的一个模型写了一个upsert方法。我希望我所有的模型都有这个upsert方法。在我看来,合乎逻辑的解决方案是定义一个继承自ActiveRecord::Base的模型,然后让我的所有其他模型继承自该模型。但如果我这样做,Rails会抱怨我创建的新模型没有一个表,这是真的,但我不在乎 既然我尝试的方法显然不是正确的方法,那么什么是正确的方法呢?有两种方法 1) 要拥有父模型,但不需要为其创建表(即抽象类),您应该设置 class YourAbstractClass < ActiveRe

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


既然我尝试的方法显然不是正确的方法,那么什么是正确的方法呢?

有两种方法

1) 要拥有父模型,但不需要为其创建表(即抽象类),您应该设置

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

    # rest of class code
end
class YourAbstractClass

2) 将该方法放在一个模块中,您可以从所有需要该方法的模型中包括该方法(如@Mark的回答)

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

就像我的应用程序的lib文件夹中有这个Utils模块一样 模块Utils

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

  ...
end
然后在我的模型中,我说

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

您可以使用模块扩展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

哇!这看起来很酷。我还没试过,但我肯定它能用+这是我给你的。是的,模块是到这里的方法。
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