This project is archived and is in readonly mode.

ActiveRecord::Base.each instance method
Reported by Guillermo Álvarez | May 17th, 2008 @ 08:37 PM
[PATCH] These patch add: ActiveRecord::Base.each ( User.each {|u| u.name} ) ActiveRecord::Base.map ActiveRecord::Base.collect
But with the diference with User.all.each that just one user is fetch from the database at a time. An simple and efficient way to don't load all the database in memmory.
With migrations between two or more databases, is common to do something like
User.find(:all).each {|u| ... } that will load all the records in memmory.
Ruby-proff says that managing that big array is not the better way.
With these patch you can do something like these.
User.each :conditions => ["users.created_at > ?", Time.now-5.months] do |u| NewUser.schema.create({ :name => u.name.Capitalize :email => validate_email u.email ... }) end
These patch pass all test, and have news ones.
Any comment are wellcome.
Comments and changes to this ticket
- 
            
         wildchild May 17th, 2008 @ 09:07 PMMy 5 cents for you (if i right understand your approach): ActiveRecord::Base.each.fetch(10) # fetch 10 records instead 1 (for small rows in example) Maybe use will_paginate there? 
- 
            
         Guillermo Álvarez May 17th, 2008 @ 08:15 PMActiveRecord::Base.each ActiveRecord::Base.map ActiveRecord::Base.collect With migrations between two or more databases, is common to do something like User.find(:all).each {|u| ... } that will load all the records in memmory. Ruby-proff says that managing that big array is not the better way. For my personal projects I use something like these: http://github.com/guillermo/acti... User.each :conditions => ["users.created_at > ?", Time.now-5.months] do |u| NewUser.schema.create({ :name => u.name.Capitalize :email => validate_email u.email ... }) end If someone think it could be interesting, i can try to make a patch. Thanks 
- 
            
         Guillermo Álvarez May 17th, 2008 @ 08:24 PMMy situation is these: desc 'Copy Posts from the phpbB3 table to the new forum' task :copy_posts => :environment do BbTopic.find(:all).each do |bb| f = Post.create({ :title => conv.iconv(bb.topic_title), :user_id => bb.topic_poster, :forum_id= bb.forum_id, ...}) end end If i run that i will get a huge array in memory that i doesn't want, so i change BbTopic.find(:all).each do |bb| to BbTopic.each do |bb| that just load one record a time. 
- 
         Tarmo Tänav May 18th, 2008 @ 06:53 PMSomething like this has already been proposed: 
- 
            
         
- 
         josh August 29th, 2008 @ 04:41 PM- State changed from new to stale
- Tag set to enhancement
 
- 
            
         Guillermo Álvarez September 9th, 2008 @ 01:37 PM- Tag changed from enhancement to activerecord, enhancement
 Hi. There is a patch to do for example Post.each. Please giveme comments since is my first patch to rails. 
- 
            
         Guillermo Álvarez September 10th, 2008 @ 09:23 AM- Assigned user set to josh
 
- 
            
         Guillermo Álvarez September 10th, 2008 @ 09:24 AM- Title changed from ActiveRecord::Base.each instance method to [PATCH] ActiveRecord::Base.each instance method
 
- 
         Pratik September 10th, 2008 @ 10:30 AM- Title changed from [PATCH] ActiveRecord::Base.each instance method to ActiveRecord::Base.each instance method
- Tag changed from activerecord, enhancement to activerecord, enhancement, patch
 
- 
         Jeremy Kemper September 10th, 2008 @ 06:12 PM- State changed from stale to open
- Milestone cleared.
 
- 
         josh September 10th, 2008 @ 06:30 PM- Assigned user changed from josh to Jeremy Kemper
 
- 
         Pratik October 17th, 2008 @ 05:13 PM- Milestone set to 2.x
 
- 
         José Valim October 19th, 2008 @ 11:36 AMHi Guillermo Álvarez, Would not be nice if your patch takes into account the option :limit and :interval? For example: @@@ruby Account.each(:interval => 10) do |account| # ...end This would query the database using 10 in 10 objects. The limit would be used if I don't want to go through all the database: @@@ruby Account.each(:interval => 10, :limit => 100) do |account| # ... endI have an implementation that I use on my projects (it's not totally abstracted as in your patches), but if it helps: @@@ruby def slow_each(options = {}) total = options.delete(:limit) || self.count(:conditions => options[:conditions]) options[:limit] = options.delete(:interval) || 1000 offset = 0 while total - offset > 0 options[:offset] = offset self.find(:all, options).each do |record| yield(record) end offset += options[:limit] endend For fast each, we can use: @@@ruby def fast_each(options = {}) total = options.delete(:limit) || self.last.id default_conditions = options.delete(:conditions) options[:limit] = options.delete(:interval) || 1000 offset = 0 while total - offset > 0 options[:conditions] = self.__send__(:merge_conditions, default_conditions, ['id BETWEEN ? AND ?', offset + 1 , offset + options[:limit]]) self.find(:all, options).each do |record| yield(record) end offset += options[:limit] end end
- 
         Jeremy Kemper February 23rd, 2009 @ 06:51 PM- State changed from open to resolved
- Milestone cleared.
 
- 
         Ryan Bigg October 9th, 2010 @ 10:01 PM- Tag cleared.
- Importance changed from  to Low
 Automatic cleanup of spam. 
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
 Alex MacCaw
      Alex MacCaw
 Cheah Chu Yeow
      Cheah Chu Yeow
 Gerrit Kaiser
      Gerrit Kaiser
 Guillermo Álvarez
      Guillermo Álvarez
 Jeremy Kemper
      Jeremy Kemper
 José Valim
      José Valim
 josh
      josh
 Pratik
      Pratik
 Ryan Bigg
      Ryan Bigg
 Tarmo Tänav
      Tarmo Tänav
 wildchild
      wildchild