Ruby on rails 干写活性装饰剂

Ruby on rails 干写活性装饰剂,ruby-on-rails,ruby,datetime,rubygems,decorator,Ruby On Rails,Ruby,Datetime,Rubygems,Decorator,我正在使用ActiveDecorator: 在编写我的UserDecorator时,我发现它有很多重叠之处。只需修饰一下datetime,但我必须反复编写decorator #冻结的字符串文字:true 模块用户装饰器 在日期时间创建的def 在时间“%Y/%m/%d%H:%m:%S”创建了\u 结束 def在日期时间确认 已确认时间为&.strftime“%Y/%m/%d%H:%m:%S” 结束 def在日期时间锁定 锁定时间为&.strftime“%Y/%m/%d%H:%m:%S” 结束 在

我正在使用ActiveDecorator:

在编写我的
UserDecorator
时,我发现它有很多重叠之处。只需修饰一下
datetime
,但我必须反复编写decorator

#冻结的字符串文字:true
模块用户装饰器
在日期时间创建的def
在时间“%Y/%m/%d%H:%m:%S”创建了\u
结束
def在日期时间确认
已确认时间为&.strftime“%Y/%m/%d%H:%m:%S”
结束
def在日期时间锁定
锁定时间为&.strftime“%Y/%m/%d%H:%m:%S”
结束
在日期时间定义当前登录
当前登录时间为&.strftime“%Y/%m/%d%H:%m:%S”
结束
定义上次在日期时间登录
上次登录时间为&.strftime“%Y/%m/%d%H:%m:%S”
结束
结束
猜猜看,在我的
AdminDecorator
上,我有完全相同的字段。我必须把所有这些都复制到AdminDecorator吗? 有什么建议吗


Ref:

我不使用
active\u 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
hook。比如:

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
中定义的五种方法


这是未经测试的,所以您可能需要稍微修改一下

我不使用
active\u 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
hook。比如:

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
中定义的五种方法


这是未经测试的,所以您可能需要稍微修改一下

我可以使用一些这样的元代码,但我无法在
AdminDecorator
中解决完全相同的字段。这意味着我仍然需要将下面的粘贴函数复制到
AdminDecorator

模块用户装饰器
DATETIME\u DECORATOR\u字段=%w[在确认时创建\u在锁定时\u在当前时\u在最后一次签名时\u在\u在锁定时]。冻结
DATETIME_DECORATOR_字段。每个do|字段|
define#method(“#{field}_datetime”)do|format=nil|
返回发送(字段)和strftime(格式)(如果是格式)
发送(字段)和.strftime“%Y/%m/%m%H:%m:%S”
结束
结束
结束
这将创建是否接受参数格式的方法:

User.first.created_at_datetime#=>“2019/06/06 16:18:02”
User.first.created_在日期时间“%Y/%m/%m”#=>“2019/06/06”

我可以使用一些类似的元代码,但我无法在
AdminDecorator
中解决完全相同的字段。这意味着我仍然需要将下面的粘贴函数复制到
AdminDecorator

模块用户装饰器
DATETIME\u DECORATOR\u字段=%w[在确认时创建\u在锁定时\u在当前时\u在最后一次签名时\u在\u在锁定时]。冻结
DATETIME_DECORATOR_字段。每个do|字段|
define#method(“#{field}_datetime”)do|format=nil|
返回发送(字段)和strftime(格式)(如果是格式)
发送(字段)和.strftime“%Y/%m/%m%H:%m:%S”
结束
结束
结束
这将创建是否接受参数格式的方法:

User.first.created_at_datetime#=>“2019/06/06 16:18:02”
User.first.created_在日期时间“%Y/%m/%m”#=>“2019/06/06”
这与和非常相似

我通常编写一些DSL方法来添加重复的方法,比如:

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
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
add\u formatter
是一种基于给定参数定义实例方法的类方法。将
format
作为可选参数只是一个示例

作为一种类方法,
add\u format
可以在类主体内部调用,如下所示:

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
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
模块最终有了各种新方法:

UserDecorator.instance_methods
#=> [
#     :confirmed_at_datetime,
#     :locked_at_datetime,
#     :current_sign_in_at_datetime,
#     :last_sign_in_at_datetime,
#     :created_at_datetime
#   ]
它们可以像往常一样被称为:

class TestUser
  include UserDecorator

  def created_at
    Time.new(2019, 7, 2, 11, 53)
  end

  def confirmed_at
    Time.new(2019, 7, 2, 11, 53)
  end
end

u = TestUser.new
u.created_at_datetime
#=> "2019/07/02 11:53:00"

u.confirmed_at_datetime
#=> "Tuesday 2, 2019"
因为您使用的是Rails,所以可能需要合并它的模式。

这与和非常类似

我通常编写一些DSL方法来添加重复的方法,比如:

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
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
add\u formatter
是一种基于给定参数定义实例方法的类方法。将
format
作为可选参数只是一个示例

作为一种类方法,
add\u format
可以在类主体内部调用,如下所示:

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
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
模块最终有了各种新方法:

UserDecorator.instance_methods
#=> [
#     :confirmed_at_datetime,
#     :locked_at_datetime,
#     :current_sign_in_at_datetime,
#     :last_sign_in_at_datetime,
#     :created_at_datetime
#   ]
它们可以像往常一样被称为:

class TestUser
  include UserDecorator

  def created_at
    Time.new(2019, 7, 2, 11, 53)
  end

  def confirmed_at
    Time.new(2019, 7, 2, 11, 53)
  end
end

u = TestUser.new
u.created_at_datetime
#=> "2019/07/02 11:53:00"

u.confirmed_at_datetime
#=> "Tuesday 2, 2019"

因为您使用的是Rails,所以可能需要合并它的模式。

Wow感谢您的详细回答!让我消化它!当然可以我以前从未见过这种宝石,不久前我使用SimpleDelegator推出了自己的宝石。既然你已经指出了这一点,也许我会仔细看看。哇,谢谢你详细的回答!让我消化它!当然可以我以前从未见过这种宝石,不久前我使用SimpleDelegator推出了自己的宝石。既然你已经指出了这一点,也许我会仔细研究一下。你的示例代码中有
%Y/%m/%m
,你可能想要
%Y/%m/%d
漂亮的捕获!谢谢我更新了!您的示例代码中有
%Y/%m/%m
,您可能想要
%Y/%m/%d
漂亮的捕获!谢谢我更新了!既然你提到了关于
activesupoport::Concern
,你能说得更多一些吗?谢谢@truongnm使添加来自其他模块的类方法和实例方法变得更加容易。按照约定,您可以简单地
包含mixin
(与
包含此模块
扩展该模块
)相反,它将处理其余部分。请查看。如果我们使用
方法\u missing
,您认为如何?@trungn