Rails 4: find all records

后端 未结 4 1890
庸人自扰
庸人自扰 2021-01-31 14:02

Now that ActiveRecord::Relation#all is deprecated in Rails 4, how are you supposed to iterate all records?

Used to be like:

Foo.all.each do |foo|
  # w         


        
相关标签:
4条回答
  • 2021-01-31 14:54

    According to the Rails Guide on Active Record Query Interface, the correct way to iterate through all records is by using find_each.

    Using Foo.all.each will load the entire table into memory, instantiating all the rows; then iterate through the instances. find_each does this in batches, which is more efficient in terms of memory usage.

    From the guide:

    The find_each method retrieves a batch of records and then yields each record to the block individually as a model. In the following example, find_each will retrieve 1000 records (the current default for both find_each and find_in_batches) and then yield each record individually to the block as a model. This process is repeated until all of the records have been processed:

    User.find_each do |user|
      NewsLetter.weekly_deliver(user)
    end
    

    References:

    • Active Record Query Interface
    • ActiveRecord::Batches
    0 讨论(0)
  • 2021-01-31 14:59

    Release notes for Rails 4:

    Model.all now returns an ActiveRecord::Relation, rather than an array of records. Use Relation#to_a if you really want an array.

    So your code will look like this:

    Foo.all.to_a.each do |foo|
      # whatever
    end
    

    See http://guides.rubyonrails.org/4_0_release_notes.html#active-record

    0 讨论(0)
  • 2021-01-31 15:04

    yes, Foo.all.

    all is deprecated on an ActiveRecord::Relation (eg. Foo.where(true)), not on ActiveRecord::Base.

    http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-all

    0 讨论(0)
  • 2021-01-31 15:06

    This appears to be an incorrect deprecation warning somewhere in Rails. As of Rails 4.0.2 the warning message still exists. I get the following error when I try and run Foo.all:

    DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (e.g. Post.where(published: true).load). If you want to get an array of records from a relation, you can call #to_a (e.g. Post.where(published: true).to_a).

    I'm almost 100% certain I watched in a RailsCasts that #all was being changed to return an Relation in Rails 4 (instead of an array) - no mention of deprecation.

    0 讨论(0)
提交回复
热议问题