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