【发布时间】:2009-05-14 14:20:47
【问题描述】:
我的所有模型中都有如下所示的方法:
def formatted_start_date
start_date ? start_date.to_s(:date) : nil
end
我想要为每个模型中的每个日期时间字段自动编写这样的方法,最好的方法是什么?
-C
【问题讨论】:
标签: ruby-on-rails activerecord model
我的所有模型中都有如下所示的方法:
def formatted_start_date
start_date ? start_date.to_s(:date) : nil
end
我想要为每个模型中的每个日期时间字段自动编写这样的方法,最好的方法是什么?
-C
【问题讨论】:
标签: ruby-on-rails activerecord model
我只需要回答这个问题,因为这是一个有趣的 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
包含后,该模块将查看任何日期列并为您生成 formatted_ 方法。
了解这些 Ruby 的工作原理。其乐无穷。
也就是说,你必须问问自己这是否有必要。我不认为这是出于个人原因,但同样,写起来很有趣。
-b-
【讨论】:
它看起来更像是我的帮手。在您的应用程序帮助中尝试此操作:
def formatted_date(date)
date ? date.to_s(:date) : nil
end
格式化并不是真正属于模型的东西(正是因为您发现的原因......在每个模型中都放置这样的通用代码很烦人)
如果你真的想按照你说的去做,那么你可以做的是对 ActiveRecord 超类进行猴子补丁并将你想要的函数添加到那里。然后它将可用于您的所有模型。请注意,monkeypatching 可能导致不可预测和未定义的行为,使用风险自负!它也很hacky :)
class ActiveRecord::Base
def formatted_start_date
start_date ? start_date.to_s(:date) : nil
end
end
只需在应用中其他任何内容之前运行的某个位置粘贴它,它就会动态地将方法添加到模型的基类中,使其可供使用。
或者您可以为所有模型创建一个 mixin,但这对于单个方法来说似乎有点矫枉过正。
【讨论】:
对您的评论的回答: 您可以将通用代码/功能提取到包含在类中的模块中(我相信这称为 mixin?),或者您可以使用子类。我不认为子类只是您想要进入对象的常用功能,而不是真正的继承情况。
【讨论】: