<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Big Dave's Blog &#187; with_scope</title>
	<atom:link href="http://davedupre.com/tag/with_scope/feed/" rel="self" type="application/rss+xml" />
	<link>http://davedupre.com</link>
	<description>Some random thoughts - Go big or stay home!</description>
	<lastBuildDate>Fri, 25 Jun 2010 15:50:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Gotcha with find_each and find_in_batches</title>
		<link>http://davedupre.com/2009/05/20/gotcha-with-find_each-and-find_in_batches/</link>
		<comments>http://davedupre.com/2009/05/20/gotcha-with-find_each-and-find_in_batches/#comments</comments>
		<pubDate>Thu, 21 May 2009 03:26:26 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[find_each]]></category>
		<category><![CDATA[find_in_batches]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[with_scope]]></category>

		<guid isPermaLink="false">http://davedupre.com/?p=315</guid>
		<description><![CDATA[Rails 2.3 added a couple of nice new methods &#8211; find_each and find_in_batches. Both methods accomplish the same thing in a slightly different way. Unlike a normal finder these methods grab objects in batches instead of all at once. For instance, if you have 500,000 users, you don&#8217;t want to do the following: User.find(:all).each { [...]]]></description>
			<content:encoded><![CDATA[<p>Rails 2.3 added a couple of nice new methods &#8211; find_each and find_in_batches. Both methods accomplish the same thing in a slightly different way. Unlike a normal finder these methods grab objects in batches instead of all at once. For instance, if you have 500,000 users, you don&#8217;t want to do the following:</p>
<pre>User.find(:all).each { |user| user.some_method }</pre>
<p>The reason is that you just loaded all 500,000 records into memory, and your server is not happy. Instead, you could do:</p>
<pre>User.find_each { |user| user.some_method }</pre>
<p>By default, the above will only load 1,000 User objects into memory, and your server will thank you. If 1,000 is too big/small for you, use the :batch_size option to change it. The find_in_batches method is similar except that it provides the array to the block instead of one object at a time. For example:</p>
<pre>User.find_in_batches do |users|
  users.each { |user| user.some_method }
end</pre>
<p>If you ever used the wonderful <a href="http://github.com/mislav/will_paginate/tree/master">will_paginate</a> gem, you are probably familiar with the concept from the paginated_each method that will_paginate provided.</p>
<p>So, what is the problem? The problem is that you have to aware that unlike paginate_each, find_each and find_in_batches work by setting up a with_scope block. Therefore, if you need to do any other finds on that same model, the scope will apply. Usually this only affects relationships, but it isn&#8217;t hard to forget. Here is an example:</p>
<pre># This is a purely made up example
class User &lt; ActiveRecord::Base
  # There is a last_login_at attribute
  named_scope :recent_login,
              lambda { |*args|
              { :conditions =&gt; ["people.last_login_at &gt;= ?", (args.first || 1.week.ago)] } }
  belongs_to :parent, :class_name =&gt; "User", :foreign_key =&gt; "parent_id"
end </pre>
<pre>User.recent_login.find_each do |user|
  parent = user.parent # This will include the recent_login scope.
end </pre>
<p>It&#8217;s no different than other with_scope issues, but it isn&#8217;t as obvious. You can get around it by doing:</p>
<pre>User.recent_login.find_each do |user|
  # Got use send because with_excusive_scope is protected.
  User.send(:with_exclusive_scope)
    parent = user.parent # This will include the recent_login scope
  end
end</pre>
<p>Now, go and be kind to your server with find_each and find_in_batches &#8211; just remember the scope.</p>
]]></content:encoded>
			<wfw:commentRss>http://davedupre.com/2009/05/20/gotcha-with-find_each-and-find_in_batches/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
