我正在使用ActiveDecorator:https://github.com/amatsuda/active_decorator
在编写UserDecorator
时,我发现它有很多重叠之处。只是装饰datetime
,但我不得不重复写很多装饰器。
# frozen_string_literal: true
module UserDecorator
def created_at_datetime
created_at&.strftime '%Y/%m/%d %H:%M:%S'
end
def confirmed_at_datetime
confirmed_at&.strftime '%Y/%m/%d %H:%M:%S'
end
def locked_at_datetime
locked_at&.strftime '%Y/%m/%d %H:%M:%S'
end
def current_sign_in_at_datetime
current_sign_in_at&.strftime '%Y/%m/%d %H:%M:%S'
end
def last_sign_in_at_datetime
last_sign_in_at&.strftime '%Y/%m/%d %H:%M:%S'
end
end
猜猜我的AdminDecorator
上的字段完全相同。我是否必须将所有这些都再次复制到AdminDecorator?
有什么建议吗?
答案 0 :(得分:5)
我不使用active_decorator
,但我想创建一个DatetimeDecorator
,就像这样:
module DatetimeDecorator
%i(
created_at
confirmed_at
locked_at
current_sign_in_at
last_sign_in_at
).each do |attr_sym|
define_method("#{attr_sym}_datetime") do
send(attr_sym)&.strftime '%Y/%m/%m %H:%M:%S'
end
end
end
无论何时包含此模块,都将获得先前在UserDecorator
中定义的五个方法,每个方法都使用相同的格式代码。
现在,要包含该模块,请使用included
钩子。像这样:
module UserDecorator
self.included(base)
base.class_eval do
include DatetimeDecorator
end
end
end
module AdminDecorator
self.included(base)
base.class_eval do
include DatetimeDecorator
end
end
end
现在,您的UserDecorator
和AdminDecorator
都具有您先前在UserDecorator
中定义的五种方法。
这是未经测试的,因此您可能需要摆弄一下。
答案 1 :(得分:2)
这与jvillian's answer和truongnm's answer非常相似。
我通常会写一些DSL方法来添加重复方法,如下所示:
async
await
是一个类方法,它基于给定的参数定义一个实例方法。将module DateFormatter
DEFAULT_FORMAT = '%Y/%m/%d %H:%M:%S'
def add_formatter(attribute, format: DEFAULT_FORMAT)
define_method("#{attribute}_datetime") do
public_send(attribute)&.strftime(format)
end
end
end
作为可选参数只是一个例子。
作为类方法,可以像这样在类体内直接调用add_formatter
:
format
add_format
模块最终具有各种新方法:
module UserDecorator
extend DateFormatter
add_formatter :created_at
add_formatter :confirmed_at, format: '%A %-d, %Y'
add_formatter :locked_at
add_formatter :current_sign_in_at
add_formatter :last_sign_in_at
end
可以像往常一样调用它们:
UserDecorator
由于使用的是Rails,因此您可能希望合并其ActiveSupport::Concern
模式。
答案 2 :(得分:1)
我可以使用类似这样的元代码,但是我无法在"Vertical"
处解决完全相同的字段。这意味着我仍然需要将下面的粘贴功能复制到AdminDecorator
:
AdminDecorator
这将创建方法是否接受参数格式:
module UserDecorator
DATETIME_DECORATOR_FIELDS = %w[created_at confirmed_at locked_at current_sign_in last_sign_in_at].freeze
DATETIME_DECORATOR_FIELDS.each do |field|
define_method("#{field}_datetime") do |format = nil|
return send(field)&.strftime(format) if format
send(field)&.strftime '%Y/%m/%m %H:%M:%S'
end
end
end