如何使方法应用于ActiveRecord对象的集合

9 ruby ruby-on-rails

目前,如果我想将一个方法应用于一组ActiveRecord对象,我必须像这样构造调用:

messages = Message.find(:all)
csv = Message.to_csv(messages)
Run Code Online (Sandbox Code Playgroud)

如何定义方法,使其结构如此?

messages = Message.find(:all)
csv = messages.to_csv
Run Code Online (Sandbox Code Playgroud)

这是当前的型号代码:

require 'fastercsv'
class Message < ActiveRecord::Base
  def Message.to_csv(messages)
    FasterCSV.generate do |csv|
      csv << ["from","to", "received"]
      for m in messages
        csv << [m.from,m.to,m.created_at]
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

web*_*mat 6

以下将在messages数组中包含的所有实例上调用to_csv.

messages = Message.find(:all)
csv = messages.map { |message| message.to_csv }
Run Code Online (Sandbox Code Playgroud)

在Rails中,在Ruby 1.9中或通过其他方式使用Symbol#to_proc,您还可以将其缩短为:

csv = messages.map(&:to_csv)
Run Code Online (Sandbox Code Playgroud)

当您想要进行更复杂的操作时,较长的形式很有用:

csv = messages.map { |message| 
  if message.length < 1000
    message.to_csv
  else
    "Too long"
  end
}
Run Code Online (Sandbox Code Playgroud)


mwi*_*ams 0

您可以在 Message 类上创建一个方法来执行以下操作:

在你的控制器中......

@csv_file = Message.send_all_to_csv
Run Code Online (Sandbox Code Playgroud)

在你的模型中...

require 'fastercsv'
class Message < ActiveRecord::Base
  def send_all_to_csv
    @messages = Find.all
    FasterCSV.generate do |csv|
      csv << ["from","to", "received"]
      for message in @messages
        csv << [message.from,message.to,message.created_at]
      end
    end
    # do something with your csv object (return it to the controller
    # or pass it on to another class method
  end
end
Run Code Online (Sandbox Code Playgroud)