Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can tell if an association is loaded with <code>loaded?</code>. </p> <p>What is happening here, if I understand your problem, is that you are trying to run a finder on an ActiveRecord::Relation. Quickly browsing through <a href="https://github.com/rails/rails/blob/c9f27e3a479e17cd94248c007e4f528026bc18f6/activerecord/lib/active_record/relation/finder_methods.rb#L95" rel="nofollow">the code</a>, it does not appear that it will try to see if a collection is loaded before it issues the query. It does, however, take a block that will avoid multiple queries. For example (the model names have been changed because I am using a sample project I created for another question):</p> <pre><code>c = Canteen.first Canteen Load (0.2ms) SELECT "canteens".* FROM "canteens" LIMIT 1 =&gt; #&lt;Canteen id: 1, name: "Really good place", created_at: "2012-12-13 00:04:11", updated_at: "2012-12-13 00:04:11"&gt; c.meals.loaded? =&gt; false c.meals.find {|m| m.id == 3} Meal Load (0.2ms) SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" = 1 =&gt; #&lt;Meal id: 3, canteen_id: 1, name: "Banana Pie", price: #&lt;BigDecimal:7fcb6784fa78,'0.499E1',18(45)&gt;, created_at: "2012-12-13 00:37:41", updated_at: "2012-12-13 00:37:41"&gt; </code></pre> <p>You see in the last example that ActiveRecord issues the query to load the associated records. This is because ActiveRecord is calling <code>to_a</code> on the association, forcing the entire set to be loaded, and then filtering based on the block conditions. Obviously, this is not ideal.</p> <p>Let's try again, eager loading the association.</p> <pre><code>c = Canteen.includes(:meals).first Canteen Load (0.2ms) SELECT "canteens".* FROM "canteens" LIMIT 1 Meal Load (0.2ms) SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" IN (1) =&gt; #&lt;Canteen id: 1, name: "Really good place", created_at: "2012-12-13 00:04:11", updated_at: "2012-12-13 00:04:11"&gt; c.meals.loaded? =&gt; true c.meals.find {|m| m.id == 3} =&gt; #&lt;Meal id: 3, canteen_id: 1, name: "Banana Pie", price: #&lt;BigDecimal:7fcb68b596f0,'0.499E1',18(45)&gt;, created_at: "2012-12-13 00:37:41", updated_at: "2012-12-13 00:37:41"&gt; </code></pre> <p>In the last example here, you see that the collection is not loaded again. Instead, the block is used to filter the already loaded records.</p> <p>As you can see below, even if the records are loaded, ActiveRecord will issue a query to grab the associated record:</p> <pre><code>c.meals.loaded? =&gt; true c.meals.find(1) Meal Load (0.1ms) SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" = 1 AND "meals"."id" = ? LIMIT 1 [["id", 1]] =&gt; #&lt;Meal id: 1, canteen_id: 1, name: "Enchiladas", price: #&lt;BigDecimal:7fcb6584ce88,'0.699E1',18(45)&gt;, created_at: "2012-12-13 00:04:40", updated_at: "2012-12-13 00:04:40"&gt; SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" = 1 AND "meals"."id" = 3 =&gt; [#&lt;Meal id: 3, canteen_id: 1, name: "Banana Pie", price: #&lt;BigDecimal:7fcb68b808e0,'0.499E1',18(45)&gt;, created_at: "2012-12-13 00:37:41", updated_at: "2012-12-13 00:37:41"&gt;] </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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