使用独立代码扩展Ruby类

时间:2012-11-11 16:50:08

标签: ruby-on-rails ruby class inheritance

我有一个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

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

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

以下是我的想法:

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

显然,它有两个原因无效:

  1. CommonItem不知道我调用的类方法。
  2. WIDTHHEIGHT常量在CommonItem而不是Item1中查找。
  3. 我尝试使用include代替extend,某些方式class_eval和类继承,但都没有效果。

    似乎我错过了一些明显的东西。请告诉我什么。

2 个答案:

答案 0 :(得分: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

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

我想我已经设法创建了一个与你的问题相似的结构。该模块正在调用Model class。

中的items类继承的方法

输出:

100
100
model_method
200
200
model_method

答案 1 :(得分:2)

在Ruby中,用于将重复代码提取到单个单元中的构造是方法

class Model
  def self.model_method
    p __method__
  end

  private

  def self.item
    p self::WIDTH, self::HEIGHT
    model_method
  end
end

class Item1 < Model
  WIDTH = 100
  HEIGHT = 100
  item
end

class Item2 < Model
  WIDTH = 200
  HEIGHT = 200
  item
end