My take on this is that the find methods belong on the model's class.
Putting a custom find in more than one place means that if you change
the model in the slightest you have to hunt down each caller of it.
An example of this was when I started splitting the image data for
uploaded pictures apart from the image meta-data such as format and
dimensions. I used to store it base64 encoded in the same table as
the meta-data, but found that:
Toon.find(1).avatars
returned a LOT of data from the model. Most of the time I don't need
it all, and while I can
put a special form of:
Toon.find(1).avatars(:all, :select => "this, that, this_other_thing")
in each place, I found using:
Toon.find(1).avatars.meta_data
worked much nicer.
Thus far, in my learning of ActiveRecord, I have mostly stuck with the model of:
class User
has_many :toons
...
end
Class Toon
belongs_to :user
...
end
and then performed searches like:
current_user.toons.each { |t|
... do something with the toon ...
}
This mostly works, and keeps items returned narrowed down to that
user. Most of the other data is either public or restricted, and
often times part of the record is public, and part is restricted. For
instance, anyone can look at the toons, but no one can look at the
user who owns them other than an admin. Also, the toon's name is
public, but some internal recordkeeping is only shown to the owner of
the toon or to an admin.
Recently, I've started adding objects which have somewhat complex
rules on who can view or modify them. Specifically, forums. In a
forum world, the owner of the forum (which is a toon or a guild) is
not the only entity which can update it, so I cannot use this clear
user.foo.bar path to get to them. In reality I could, but that would
make one huge SQL statement, which just won't cut it.
So, how am I getting around this?
I made custom finders for forums. For one, I have one that takes a
Toon class as a finder:
Forums.find_for_toon(:all, :toon => Toon.find(1), :access => :read)
for instance. This finder takes all the standard find parameters, but
also adds a condition to the list of ones supplied by the user, and
returns a list of forums the Toon in question can access.
Even then, this is a huge database hit. Luckily I can do it mostly in
one select, and weed through the output. Unluckily, there is
potentially a lot of output.
--Michael