ruby on rails模型的全局方法

我的所有模型中的方法都是这样的:

def formatted_start_date start_date ? start_date.to_s(:date) : nil end 

我希望能为每个模型中的每个日期时间字段自动编写这样的方法,这样做的最佳方法是什么?

-C

我只需回答这个问题,因为这是一个有趣的Ruby练习。

向类添加方法可以通过多种方式完成,但最好的方法之一是使用Ruby的一些reflection和评估function。

在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 

格式化不是真正属于模型的东西(正是因为你发现了……在每个模型中放置这样的公共代码都很烦人)

如果你真的想像你说的那样做,那么你可以做的就是monkeypatch ActiveRecord超类并将你想要的function添加到那里。 然后它将适用于您的所有型号。 请注意,monkeypatching可能导致不可预测和未定义的行为,使用风险自负! 这也很hacky 🙂

 class ActiveRecord::Base def formatted_start_date start_date ? start_date.to_s(:date) : nil end end 

只需坚持将在应用程序中的任何其他内容之前运行的某个地方,它将动态地将该方法添加到模型的基类中,使其可供使用。

或者你可以为你的所有模型创建一个mixin,但这对于单个方法来说似乎有点过分。

您的评论的答案:您可以将常用代码/function提取到您包含在类中的模块中(我相信这称为mixin?),或者您可以选择子类。 我不认为子类是它想要进入对象的常见function,而不是真正的inheritance情况。

有关模块和Ruby的更多信息,请查看此内容 。