ruby on rails模型的全局方法

时间:2009-05-14 14:20:48

标签: ruby-on-rails activerecord model

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

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

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

-C

3 个答案:

答案 0 :(得分:16)

我只需回答这个问题,因为这是一个有趣的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 -

答案 1 :(得分:11)

看起来更像是帮助我的东西。请在您的应用程序帮助中尝试此操作:

def formatted_date(date)
   date ? date.to_s(:date) : nil
end

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

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

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

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

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

答案 2 :(得分:0)

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

看看this for more info on modules and Ruby