title: How can I tell ActiveRecord to discard an association cache AFTER a where clause
body: <p>I'm trying to refresh an ActiveRecord has_many association also using a where clause. I'm finding two things that confuse me:</p>
  
  <ol>
  <li>ActiveRecord does not use the cached association if there you call where on the association</li>
  <li>Forcing ActiveRecord to query the db by passing true to the association method will fetch all the associations before the where clause is considered, causing an inefficient and unnecessary load of many objects into memory.</li>
  </ol>
  
  <p>Is (1) expected behavior? [UPDATE -- see Frederick Cheung's answer below; each call generates a new relation so I believe the answer to this is yes]  I can't find this in the docs, so I feel iffy relying on my observation. If it is, then (2) is moot since AR will query the db each time anyway without telling it to force reload. But since I don't know, I have the follow-up question in case (1) is not guaranteed: How can I force reload without immediate query execution?</p>
  
  <p>To illustrate (outputs are suppressed because they are not relevant, only the AR log output is shown):</p>
  
  <p><code>MediaFile</code> <code>has_many :assets</code></p>
  
  <p>Caching and forcing refresh works as expected:</p>
  
  <pre><code>m = MediaFile.delivered.offset(20).last
  ### log suppressed
  1.9.3-p448 :078 &gt; m.assets.map(&amp;:id); nil
    MediaAsset Load (0.3ms)  SELECT `media_assets`.* FROM `media_assets` WHERE (`media_assets`.media_file_id = 533849)
  1.9.3-p448 :079 &gt; m.assets.map(&amp;:id); nil
  1.9.3-p448 :080 &gt; m.assets(true).map(&amp;:id); nil
    MediaAsset Load (0.3ms)  SELECT `media_assets`.* FROM `media_assets` WHERE (`media_assets`.media_file_id = 533849)
  </code></pre>
  
  <p><code>where</code> clauses force a db fetch:</p>
  
  <pre><code>1.9.3-p448 :081 &gt; m.assets.where(type: "Source").map(&amp;:id); nil
    MediaAsset Load (0.3ms)  SELECT `media_assets`.* FROM `media_assets` WHERE (`media_assets`.media_file_id = 533849) AND (`media_assets`.`type` = 'Source')
  1.9.3-p448 :082 &gt; m.assets.where(type: "Source").map(&amp;:id); nil
    MediaAsset Load (0.3ms)  SELECT `media_assets`.* FROM `media_assets` WHERE (`media_assets`.media_file_id = 533849) AND (`media_assets`.`type` = 'Source')
  </code></pre>
  
  <p>Passing true to the association method forces immediate loading:</p>
  
  <pre><code>1.9.3-p448 :083 &gt; m.assets(true).where(type: "Source").map(&amp;:id); nil
    MediaAsset Load (0.3ms)  SELECT `media_assets`.* FROM `media_assets` WHERE (`media_assets`.media_file_id = 533849)
    MediaAsset Load (0.2ms)  SELECT `media_assets`.* FROM `media_assets` WHERE (`media_assets`.media_file_id = 533849) AND (`media_assets`.`type` = 'Source')
  </code></pre>
  
  <p>Note that the first query in this last example executed first without the where clause. This seems suboptimal. </p>