从包含的同名模块方法获取Model属性

时间:2014-02-19 19:17:31

标签: ruby-on-rails ruby

我想创建一个可以包含在不同模型中的常见映射功能的关注点。除非已经设置了包含Model的同名属性,否则此模块将具有返回计算值的方法。

例如:

module Mappable
  extend ActiveSupport::Concern

  included do
    has_one :map, as: :mappable, dependent: :destroy
  end

  def centroid
    Point('123.45 321.21')  #whatever
  end

  def longitude
    super || centroid.x
  end

  def latitude
    super || centroid.y
  end
end

因此,方法中的“超级”将是模型的“经度”或“纬度”属性。如果未设置,请从 centroid 中获取。

更新

我的代码实际上是按照书面编写的。我没有正确测试这个问题。

2 个答案:

答案 0 :(得分:0)

您可以使用ruby提供的defined?方法

def longitude
  if defined?(super)
    super || centroid.x
  else
    centroid.x
  end
end

def latitude
  if defined?(super)
    super || centroid.y
  else
    centroid.y
  end
end

答案 1 :(得分:0)

您可以覆盖该方法并依赖ActiveRecord模型的attributes哈希值(存储值的位置):

module Mappable
  extend ActiveSupport::Concern

  def longitude
    attributes[:longitude] || centroid.x
  end

  # etc...
end

我自己没有使用过这种技术,所以可能会有一些我没有想过的问题。写一些测试并尝试一下。