【问题标题】:Extending a Ruby class with a standalone piece of code用一段独立的代码扩展一个 Ruby 类
【发布时间】:2012-10-31 06:13:33
【问题描述】:

我有一个 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 和类继承的一些方法,但没有任何工作。

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

【问题讨论】:

标签: ruby-on-rails ruby class inheritance


【解决方案1】:

我会这样做:

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

【讨论】:

  • 不错!我没有想到使用 self.included 钩子。这肯定是一个解决方案。
【解决方案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

【讨论】:

  • 投反对票的人能解释一下吗?这段代码完美地解决了 OP 的问题,它与@Dogbert 的代码具有完全相同的行为,同时更简单,不需要任何形式的元编程、反射或钩子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 2020-10-05
  • 1970-01-01
相关资源
最近更新 更多