<p>I have a few models that need to have custom find conditions placed on them.  For example, if I have a Contact model, every time Contact.find is called, I want to restrict the contacts returned that only belong to the Account in use.</p>

<p>I found this via Google (which I've customized a little):</p>

<pre><code>def self.find(*args)
  with_scope(:find =&gt; { :conditions =&gt;  "account_id = #{$account.id}" }) do
    super(*args)
  end
end
</code></pre>

<p>This works great, except for a few occasions where account_id is ambiguous so I adapted it to:</p>

<pre><code>def self.find(*args)
  with_scope(:find =&gt; { :conditions =&gt;  "#{self.to_s.downcase.pluralize}.account_id = #{$account.id}" }) do
    super(*args)
  end
end
</code></pre>

<p>This also works great, however, I want it to be DRY.  Now I have a few different models that I want this kind of function to be used.  What is the best way to do this?</p>

<p>When you answer, please include the code to help our minds grasp the metaprogramming Ruby-fu.</p>

<p>(I'm using Rails v2.1)</p>

[{'answer_id': 80440, 'author': 'Jean', 'author_id': 7898, 'author_profile': 'https://Stackoverflow.com/users/7898', 'pm_score': 4, 'selected': True, 'text': '<p>You don\'t tell us which version of rails you are using [edit - it is on rails 2.1 thus following advice is fully operational], but I would recommand you use the following form instead of overloading find yourself : </p>\n\n<pre><code>account.contacts.find(...) \n</code></pre>\n\n<p>this will automatically wrap the find in a scope where the user clause is included (since you have the account_id I assume you have the account somewhere close)</p>\n\n<p>I suggest you check the following resources on scopes</p>\n\n<ul>\n<li><a href="http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality" rel="nofollow noreferrer">http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality</a>\n(this is not edge anymore :) )</li>\n<li><a href="http://ryandaigle.com/articles/2008/8/20/named-scope-it-s-not-just-for-conditions-ya-know" rel="nofollow noreferrer">http://ryandaigle.com/articles/2008/8/20/named-scope-it-s-not-just-for-conditions-ya-know</a></li>\n</ul>\n'}, {'answer_id': 80610, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>to give a specific answer to your problem, I\'d suggest moving the above mentioned method into a module to be included by the models in question; so you\'d have </p>\n\n<pre><code>class Contact\n  include NarrowFind\n  ...\nend\n</code></pre>\n\n<p>PS. watch out for sql escaping of the account_id, you should probably use the <code>:conditions=&gt;["....  =?", $account_id]</code> syntax.</p>\n'}, {'answer_id': 83010, 'author': 'Nathan de Vries', 'author_id': 11109, 'author_profile': 'https://Stackoverflow.com/users/11109', 'pm_score': 3, 'selected': False, 'text': "<p>Jean's advice is sound. Assuming your models look like this:</p>\n\n<pre><code>class Contact &lt; ActiveRecord::Base\n  belongs_to :account\nend\n\nclass Account &lt; ActiveRecord::Base\n  has_many :contacts\nend\n</code></pre>\n\n<p>You should be using the <code>contacts</code> association of the current account to ensure that you're only getting <code>Contact</code> records scoped to that account, like so:</p>\n\n<pre><code>@account.contacts\n</code></pre>\n\n<p>If you would like to add further conditions to your contacts query, you can specify them using find:</p>\n\n<pre><code>@account.contacts.find(:conditions =&gt; { :activated =&gt; true })\n</code></pre>\n\n<p>And if you find yourself constantly querying for activated users, you can refactor it into a named scope:</p>\n\n<pre><code>class Contact &lt; ActiveRecord::Base\n  belongs_to :account\n  named_scope :activated, :conditions =&gt; { :activated =&gt; true }\nend\n</code></pre>\n\n<p>Which you would then use like this:</p>\n\n<pre><code>@account.contacts.activated\n</code></pre>\n"}]
['https://Stackoverflow.com/questions/80424', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/14530/']