我所有的模型都有类似这样的方法:
def formatted_start_date
start_date ? start_date.to_s(:date) : nil
end
我希望有一种自动为每个模型中的每个日期时间字段编写此类方法的工具,最好的方法是什么?
-C
我所有的模型都有类似这样的方法:
def formatted_start_date
start_date ? start_date.to_s(:date) : nil
end
我必须回答这个问题,因为这是一个有趣的Ruby练习。
向类添加方法可以通过多种方式完成,但其中一种最简洁的方法是使用Ruby的一些反射和评估功能。
在你的 lib 文件夹中创建此文件作为 lib/date_methods.rb。
module DateMethods
def self.included(klass)
# get all dates
# Loop through the class's column names
# then determine if each column is of the :date type.
fields = klass.column_names.select do |k|
klass.columns_hash[k].type == :date
end
# for each of the fields we'll use class_eval to
# define the methods.
fields.each do |field|
klass.class_eval <<-EOF
def formatted_#{field}
#{field} ? #{field}.to_s(:date) : nil
end
EOF
end
end
end
现在只需将它包含在需要它的任何模型中即可。
class CourseSection < ActiveRecord::Base
include DateMethods
end
当包含此模块时,它将查看任何日期列并为您生成已格式化的方法。
学习如何使用Ruby。这很有趣。
话虽如此,你必须问自己这是否必要。我个人认为不是,但再次写起来很有趣。
-b-
在我看来,它更像是一个帮手。在你的应用程序帮助中尝试这个:
def formatted_date(date)
date ? date.to_s(:date) : nil
end
格式化并不是模型应该包含的内容(正如你所发现的那样...在每个模型中放置这样的共同代码很烦人)
如果你真的想按照你说的那样做,那么你可以猴子补丁 ActiveRecord 的超类,并在其中添加你想要的函数。它将在所有你的模型中都可用。请注意,猴子补丁可能会导致无法预测和未定义的行为,请自行承担风险! 它也相当的 hacky :)
class ActiveRecord::Base
def formatted_start_date
start_date ? start_date.to_s(:date) : nil
end
end
只需将其放在应用程序中任何其他内容运行之前的位置,它将动态地将该方法添加到您的模型基类中,使其可供使用。
或者您可以为所有模型创建一个混合类,但是对于单个方法来说,这似乎有点过头了。
回复您的评论: 您可以将常见的代码/功能提取到模块中,然后将其包含在类中(我认为这被称为mixin?),或者您可以选择子类。当您只想将常见功能放入对象中而不是真正的继承情况时,我不认为子类是可行的方法。