5

我有一个带有多个具有相同结构的模型的 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.

我尝试使用一些方法和类继承来include代替,但没有一个工作。extendclass_eval

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

4

2 回答 2

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

输出:

100
100
model_method
200
200
model_method
于 2012-11-11T17:15:00.700 回答
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
于 2012-11-11T17:37:51.413 回答