How to filter find(:all)

We're going to be changing our system soon to implement the concept of
a trash can. Basically when user deletes things they will get flagged
as 'trash' and won't be deleted until the user goes into the trash
area and explicitly deletes them. The way we'll do this is set a field
in the tables, say 'trash' to 1 if trashed, 0 if active.
What I don't want to have to do though is go back and change every
line like

Posts.find(:all)

to something like

Posts.find(:all, :conditions => 'trash = 0')

as I'm sure it will get very messy. Is there someway to do this in the
model so that generally only active posts get returned while the
trashed stuff requires a specific call - say something like

Posts.find_trashed(:all)

or

Posts.find_trashed('123')

Thanks for any help on this.

Dale

Sure!
In your Post model:

def self.find_trashed
  find(all, :conditions => ['trashed = 1'])
end

Do the same with find_untrashed, etc.

I never put such business logic in my controllers. Whenever I am tempted
to write Post.find(:all, :conditions => ...), I define a new class method
(self.) in my model. The code is *really* cleaner.

My $0.02

Take a look at acts_as_paranoid (http://ar-paranoid.rubyforge.org/) - somewhat
of an overkill for your scenario, but the ideas are similar. Using a similar
strategy will let you keep all your normal find(:all) calls as they are.

  --mdj

Whoops, maybe I wasn't clear here - the idea is to NOT write the
find_untrashed function. It's to have find(:all) (or any other
variation of the standard find procedures) return only the non-trashed
items.

if you have a 'trashed' column in your database, you will have a
trashed attribute in your model. Rails will automatically add finders
for all the attributes in your model.

so you will have access to

find_by_trash(<value>) # finds first where trash = <value>
find_all_by_trash(<value>) #f finds all where trash = <value>

I'd say the performance hit is negligible

PartSearch.count

=> 99588

puts Benchmark.measure { PartSearch.find_all_by_part('lm311') }

  0.033333 0.000000 0.033333 ( 0.296591)
=> nil

puts Benchmark.measure { PartSearch.find(:all, :conditions =>

["part = ?", "lm311"]) }
  0.000000 0.000000 0.000000 ( 0.233105)
=> nil

puts Benchmark.measure { PartSearch.find(:all, :conditions => "part

= 'lm311'") }
  0.000000 0.000000 0.000000 ( 0.348846)
=> nil