Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You're seeing an artifact of using <code>irb</code> to investigate things.</p> <p>When you say this:</p> <pre><code>&gt; Product.first.title #=&gt; nil </code></pre> <p>Your <code>method_missing</code> will be called to lazy-load the <code>title</code> method and you get <code>nil</code>.</p> <p>When you say this:</p> <pre><code>&gt; Product.first </code></pre> <p>You're effectively doing this:</p> <pre><code>&gt; p = Product.first; puts p.inspect </code></pre> <p>The first Product instance will be loaded and then <code>irb</code> will call <code>inspect</code> on it and AR will add the accessor methods along the way. The result is that Product will now have a <code>title</code> method. Hence, doing this:</p> <pre><code>&gt; Product.first &gt; Product.first.title </code></pre> <p>won't call your <code>method_missing</code> at all as there will be a real <code>title</code> method for <code>Product.first.title</code> to call.</p> <p>If you try again like this:</p> <pre><code>&gt; Product.first; nil &gt; Product.first.title </code></pre> <p>You'll see two <code>nil</code>s.</p> <hr> <p>As far as chaining goes, ActiveRecord doesn't really detect the end, it is just that some method calls naturally require real data from the database and some don't.</p> <p>If you call <code>where</code>, <code>order</code>, or any of the other querying methods, you get an <a href="http://api.rubyonrails.org/classes/ActiveRecord/Relation.html" rel="nofollow noreferrer">ActiveRecord::Relation</a> instance back and you can chain more query methods and scopes on that relation object. For example, <a href="https://github.com/rails/rails/blob/c8b584f57625d6b2459c70b6746ab3729f2fde8f/activerecord/lib/active_record/relation/query_methods.rb#L132" rel="nofollow noreferrer"><code>where</code></a> (which ActiveRecord::Relation gets by including <a href="http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html" rel="nofollow noreferrer">ActiveRecord::QueryMethods</a>) looks like this:</p> <pre><code>def where(opts, *rest) return self if opts.blank? relation = clone relation.where_values += build_where(opts, rest) relation end </code></pre> <p>so it just makes a copy of the current query, adds a few things to the copy, and gives you the copy back.</p> <p>If you call <code>first</code>, <code>last</code>, <code>to_a</code>, <code>all</code>, any of the <a href="http://www.ruby-doc.org/core-1.9.3/Enumerable.html" rel="nofollow noreferrer">Enumerable</a> methods (i.e. you call <code>each</code>), ... then you're asking about specific instances and ActiveRecord will have to execute the query to realize the model instance(s) in question. For example, <a href="https://github.com/rails/rails/blob/d22592a05b299c21e30ec8b38890a178dca863b4/activerecord/lib/active_record/relation.rb#L149" rel="nofollow noreferrer"><code>ActiveRecord::Relation#to_a</code></a> looks like this:</p> <pre><code>def to_a logging_query_plan do exec_queries end end </code></pre> <p>and <a href="https://github.com/rails/rails/blob/d22592a05b299c21e30ec8b38890a178dca863b4/activerecord/lib/active_record/relation/finder_methods.rb#L158" rel="nofollow noreferrer"><code>all</code></a> is little more than a wrapper around <code>to_a</code>.</p> <p>ActiveRecord doesn't really know where the end of the chain is, it just doesn't load anything from the database until it has to so you tell it where the chain ends by saying <em>go forth and retrieve me some data</em>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload