使用独立代码扩展Ruby类

Iva*_*van 5 ruby inheritance ruby-on-rails class

我有一个Rails应用程序,其中有几个具有相同结构的模型:

class Item1 < ActiveRecord::Base
  WIDTH = 100
  HEIGHT = 100
  has_attached_file :image, styles: {original: "#{WIDTH}x#{HEIGHT}"}
  validates_attachment :image, :presence => true
end


class Item2 < ActiveRecord::Base
  WIDTH = 200
  HEIGHT = 200
  has_attached_file :image, styles: {original: "#{WIDTH}x#{HEIGHT}"}
  validates_attachment :image, :presence => true
end
Run Code Online (Sandbox Code Playgroud)

实际的代码更复杂,但这足以简化.

我想我可以将代码的公共部分放在一个地方,然后在所有模型中使用它.

以下是我的想法:

class Item1 < ActiveRecord::Base
  WIDTH = 100
  HEIGHT = 100
  extend CommonItem
end

module CommonItem
  has_attached_file :image, styles: {original: "#{WIDTH}x#{HEIGHT}"}
  validates_attachment :image, :presence => true
end
Run Code Online (Sandbox Code Playgroud)

显然它不起作用有两个原因:

  1. CommonItem 我不知道我调用的类方法.
  2. WIDTH并且HEIGHT查找常量CommonItem而不是Item1.

我尝试使用include而不是extend某种方式class_eval和类继承,但没有工作.

看来我遗漏了一些明显的东西.请告诉我什么.

Dog*_*ert 3

我会这样做:

class Model
  def self.model_method
    puts "model_method"
  end
end

module Item
  def self.included(base)
    base.class_eval do
      p base::WIDTH, base::HEIGHT
      model_method
    end
  end
end

class Item1 < Model
  WIDTH = 100
  HEIGHT = 100
  include Item
end

class Item2 < Model
  WIDTH = 200
  HEIGHT = 200
  include Item
end
Run Code Online (Sandbox Code Playgroud)

included当包含模块时,会在模块上调用该方法。

我想我已经成功创建了与您的问题类似的结构。该模块正在调用项目类从类继承的方法Model

输出:

100
100
model_method
200
200
model_method
Run Code Online (Sandbox Code Playgroud)