<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: A Couple Rails Find Gotchas</title>
	<atom:link href="http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/</link>
	<description>Addressing such topics as: web programming, design, ruby on rails, cake php, postgresql, linux, seo</description>
	<lastBuildDate>Sat, 12 Nov 2011 05:39:30 -0700</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Marnen Laibow-Koser</title>
		<link>http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/comment-page-1/#comment-492</link>
		<dc:creator>Marnen Laibow-Koser</dc:creator>
		<pubDate>Mon, 18 May 2009 15:51:14 +0000</pubDate>
		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=59#comment-492</guid>
		<description>I just confirmed that I was correct about this. Look at .methods on any ActiveRecord class, then run .find_by_whatever and look at .methods again. You&#039;ll see that .methods has gained a &#039;find_by_whatever&#039; entry.</description>
		<content:encoded><![CDATA[<p>I just confirmed that I was correct about this. Look at .methods on any ActiveRecord class, then run .find_by_whatever and look at .methods again. You&#8217;ll see that .methods has gained a &#8216;find_by_whatever&#8217; entry.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Marnen Laibow-Koser</title>
		<link>http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/comment-page-1/#comment-490</link>
		<dc:creator>Marnen Laibow-Koser</dc:creator>
		<pubDate>Sat, 16 May 2009 06:27:54 +0000</pubDate>
		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=59#comment-490</guid>
		<description>[Resubmitting with nonbreaking spaces for indentation.]

Dan Ahern: AFAIK, the named finders are *not* a performance problem. I haven’t verified this in the ActiveRecord source code, but I remember reading (on the Rails list?) that AR is rather clever in this regard.

Basically, IIRC, method_missing is invoked *only the first time* that a named finder is encountered, then it caches the method for future calls. I guess it would be something like this (in concept, not necessarily implementation):

class Person &lt; ActiveRecord::Base
  def method_missing(name, *args, &amp;block)
    if name.to_s =~ /^find_by_/
      method = Proc.new { #some dynamic finder code }
      class &lt;&lt; self.class
        self.define_method(name, method)
      end
      self.send(name, *args, block)
    end
  end
end

…so that the first time Person.find_by_name is called, you do incur the method_missing overhead — but the second time Person.find_by_name is called, it exists as a real method, so method_missing doesn’t come into play.

So don’t worry about dynamic finders for performance, so long as you’re not using too many different ones.</description>
		<content:encoded><![CDATA[<p>[Resubmitting with nonbreaking spaces for indentation.]</p>
<p>Dan Ahern: AFAIK, the named finders are *not* a performance problem. I haven’t verified this in the ActiveRecord source code, but I remember reading (on the Rails list?) that AR is rather clever in this regard.</p>
<p>Basically, IIRC, method_missing is invoked *only the first time* that a named finder is encountered, then it caches the method for future calls. I guess it would be something like this (in concept, not necessarily implementation):</p>
<p>class Person &lt; ActiveRecord::Base<br />
  def method_missing(name, *args, &amp;block)<br />
    if name.to_s =~ /^find_by_/<br />
      method = Proc.new { #some dynamic finder code }<br />
      class &lt;&lt; self.class<br />
        self.define_method(name, method)<br />
      end<br />
      self.send(name, *args, block)<br />
    end<br />
  end<br />
end</p>
<p>…so that the first time Person.find_by_name is called, you do incur the method_missing overhead — but the second time Person.find_by_name is called, it exists as a real method, so method_missing doesn’t come into play.</p>
<p>So don’t worry about dynamic finders for performance, so long as you’re not using too many different ones.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dan Ahern</title>
		<link>http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/comment-page-1/#comment-486</link>
		<dc:creator>Dan Ahern</dc:creator>
		<pubDate>Wed, 13 May 2009 02:49:47 +0000</pubDate>
		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=59#comment-486</guid>
		<description>No problem, I really fell in love with the hash style syntax when I first realized it was available.  It just makes a lot more sense than the Array format.  

One thing while I was digging around in to the BDD world that I found today was Squirrel by ThoughtBot.  

http://www.thoughtbot.com/projects/squirrel/

This allows for Ruby blocks into the find method.  I haven&#039;t had a chance to use this yet but I think it would help to move completely out of the ActiveRecord Array conditions syntax.</description>
		<content:encoded><![CDATA[<p>No problem, I really fell in love with the hash style syntax when I first realized it was available.  It just makes a lot more sense than the Array format.  </p>
<p>One thing while I was digging around in to the BDD world that I found today was Squirrel by ThoughtBot.  </p>
<p><a href="http://www.thoughtbot.com/projects/squirrel/" rel="nofollow">http://www.thoughtbot.com/projects/squirrel/</a></p>
<p>This allows for Ruby blocks into the find method.  I haven&#8217;t had a chance to use this yet but I think it would help to move completely out of the ActiveRecord Array conditions syntax.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel</title>
		<link>http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/comment-page-1/#comment-484</link>
		<dc:creator>Daniel</dc:creator>
		<pubDate>Thu, 30 Apr 2009 15:02:34 +0000</pubDate>
		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=59#comment-484</guid>
		<description>Thanks for the pointers. They should clean up my code a bit as the hash conditions are a lot more readable than the array ones. Yet all too often I still find myself needing &lt;, &gt; or IS NOT NULL.</description>
		<content:encoded><![CDATA[<p>Thanks for the pointers. They should clean up my code a bit as the hash conditions are a lot more readable than the array ones. Yet all too often I still find myself needing < , > or IS NOT NULL.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dan Ahern</title>
		<link>http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/comment-page-1/#comment-483</link>
		<dc:creator>Dan Ahern</dc:creator>
		<pubDate>Wed, 29 Apr 2009 23:53:19 +0000</pubDate>
		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=59#comment-483</guid>
		<description>Hi Daniel,
I would like to point out a couple of things.  First off, I would tend to avoid writing code with the named finders.  The reason for this is that they are really a hack, what they do is wait for the undefined method error and then catch it and build the query from there.  Repetitive use of those can slow your page load down.

Second, what I would recommend rather than using the array conditions method is to instead switch over to using a hash, much of the issue would be easily solved by using the hash.  For example
Client.find(:all, :conditions =&gt; {:notify_by =&gt; %w(email txt both)}) will generate an sql query SELECT * FROM clients WHERE notify_by in (&#039;email&#039;,&#039;txt&#039;,&#039;both&#039;);

With the new Rails 2.2+ you can do neat things with the conditions hash as well like putting a condition for another table.
Client.find(:all, :conditions =&gt; {&#039;projects.payment_type&#039; =&gt; %w(paying nonpaying both)}, :join =&gt; :project)
will generate 
SELECT * FROM clients LEFT JOIN projects on clients.id = projects.client_id WHERE projects.payment_type in (&#039;paying&#039;,&#039;nonpaying&#039;,&#039;both&#039;);

You also aren&#039;t just limited to arrays.  
Client.find(:all, :conditions =&gt; {:activated =&gt; true})
Will generate the expected where activated = 1
Client.find(:all, :conditions =&gt; {:created_at =&gt; (Time.now-30.days)..Time.now})
Will generate created_at BETWEEN (&#039;2009-04-1&#039;, &#039;2009-04-30&#039;)
Client.find(:all, :conditions =&gt; {:agent =&gt; nil})
Will generate agent IS NULL

The only time you should need to slip back to your array conditions is when you have to do less than () or when dealing with much more complex conditions statements.</description>
		<content:encoded><![CDATA[<p>Hi Daniel,<br />
I would like to point out a couple of things.  First off, I would tend to avoid writing code with the named finders.  The reason for this is that they are really a hack, what they do is wait for the undefined method error and then catch it and build the query from there.  Repetitive use of those can slow your page load down.</p>
<p>Second, what I would recommend rather than using the array conditions method is to instead switch over to using a hash, much of the issue would be easily solved by using the hash.  For example<br />
Client.find(:all, :conditions =&gt; {:notify_by =&gt; %w(email txt both)}) will generate an sql query SELECT * FROM clients WHERE notify_by in (&#8217;email&#8217;,'txt&#8217;,'both&#8217;);</p>
<p>With the new Rails 2.2+ you can do neat things with the conditions hash as well like putting a condition for another table.<br />
Client.find(:all, :conditions =&gt; {&#8217;projects.payment_type&#8217; =&gt; %w(paying nonpaying both)}, :join =&gt; :project)<br />
will generate<br />
SELECT * FROM clients LEFT JOIN projects on clients.id = projects.client_id WHERE projects.payment_type in (&#8217;paying&#8217;,'nonpaying&#8217;,'both&#8217;);</p>
<p>You also aren&#8217;t just limited to arrays.<br />
Client.find(:all, :conditions =&gt; {:activated =&gt; true})<br />
Will generate the expected where activated = 1<br />
Client.find(:all, :conditions =&gt; {:created_at =&gt; (Time.now-30.days)..Time.now})<br />
Will generate created_at BETWEEN (&#8217;2009-04-1&#8242;, &#8216;2009-04-30&#8242;)<br />
Client.find(:all, :conditions =&gt; {:agent =&gt; nil})<br />
Will generate agent IS NULL</p>
<p>The only time you should need to slip back to your array conditions is when you have to do less than () or when dealing with much more complex conditions statements.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

