fyl*_*ooi 5 ruby ruby-on-rails
我正在创建一个演示者基类,它应该包装一个 ActiveRecord 对象。
class BasePresenter
def initialize object
@object = object
end
def method_missing(*args, &block)
@object.send(*args, &block)
end
def self.wrap collection
collection.map { |item| new item }
end
end
Run Code Online (Sandbox Code Playgroud)
对于每个子类,我希望能够在初始化时根据子属性动态定义一个方法,因此 ListPresenter 如下所示:
class ListPresenter < BasePresenter
end
Run Code Online (Sandbox Code Playgroud)
应该list_id使用包装的 List 对象的 id 进行响应。
如果没有在每个子类上定义它,我该怎么做?我在 中尝试了以下方法def initialize(object),但都不起作用。eval如果可能的话,我宁愿避免基于方法,因为我听说这是一种代码气味。
类方法(将方法添加到 BasePresenter,而不是子类)
self.class.send(:define_method, "#{object.class.name.underscore}_id") do
@object.id
end
Run Code Online (Sandbox Code Playgroud)
元类方法(无法访问实例变量object或@object):
class << self
define_method "#{@object.class.name.underscore}_id" do
@object.id
end
end
Run Code Online (Sandbox Code Playgroud)
Class#inherited每当子类继承BasePresenter时,使用hook动态添加一个方法。
class BasePresenter
def self.inherited(sub_klass)
sub_klass.send(:define_method, "#{sub_klass.name.underscore.split("_")[0...-1].join("_")}_id") do
instance_variable_get("@object").id
end
end
end
class ListPresenter < BasePresenter
end
# Sending a rails model object below
l = ListPresenter.new(User.first)
l.list_id #=> 1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1166 次 |
| 最近记录: |