# How to filter find(:all)

**URL:** <https://www.ruby-forum.com/t/how-to-filter-find-all/88774>\
**Category:** Rails\
**Created:** [March 14, 2007, 9:18am UTC](https://www.ruby-forum.com/t/how-to-filter-find-all/88774 "2007-03-14T09:18:52Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![PeteSalty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bc79bd/32.png) [@PeteSalty](https://www.ruby-forum.com/u/PeteSalty)\
**Post date:** [March 14, 2007, 9:18am UTC](https://www.ruby-forum.com/t/how-to-filter-find-all/88774/1 "2007-03-14T09:18:52Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![PeteSalty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bc79bd/32.png) [@PeteSalty](https://www.ruby-forum.com/u/PeteSalty)\
**Post date:** [March 14, 2007, 9:47am UTC](https://www.ruby-forum.com/t/how-to-filter-find-all/88774/2 "2007-03-14T09:47:54Z")

</div>

On Wed, Mar 14, 2007 at 01:17:36AM -0700, PeteSalty wrote :

> 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’)

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

–  
,========================.  
| Pierre-Alexandre M. |  
| email : removed\_email\_address@domain.invalid |  
`========================’

---

<div class="post-metadata">

**Author:** ![PeteSalty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bc79bd/32.png) [@PeteSalty](https://www.ruby-forum.com/u/PeteSalty)\
**Post date:** [March 14, 2007, 7:09pm UTC](https://www.ruby-forum.com/t/how-to-filter-find-all/88774/3 "2007-03-14T19:09:50Z")

</div>

Take a look at acts\_as\_paranoid ([http://ar-paranoid.rubyforge.org/](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

On 3/14/07, PeteSalty [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> or
> 
> Posts.find\_trashed(‘123’)
> 
> Thanks for any help on this.
> 
> Dale
> 
> >

–  
Matt J.  
removed\_email\_address@domain.invalid  
President/Technical Director, Acme Art Company ([acmeartco.org](http://acmeartco.org))

---

<div class="post-metadata">

**Author:** ![PeteSalty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bc79bd/32.png) [@PeteSalty](https://www.ruby-forum.com/u/PeteSalty)\
**Post date:** [March 15, 2007, 11:57am UTC](https://www.ruby-forum.com/t/how-to-filter-find-all/88774/4 "2007-03-15T11:57:56Z")

</div>

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() # finds first where trash =   
find\_all\_by\_trash() #f finds all where trash =

---

<div class="post-metadata">

**Author:** ![PeteSalty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bc79bd/32.png) [@PeteSalty](https://www.ruby-forum.com/u/PeteSalty)\
**Post date:** [March 15, 2007, 4:02pm UTC](https://www.ruby-forum.com/t/how-to-filter-find-all/88774/5 "2007-03-15T16:02:16Z")

</div>

I would go with the method approach (using find\_by\_sql or find), as  
dynamic finders will cost you performance wise

ex.

def find\_active\_posts  
find(all, :conditions =\> [‘trashed = 0’])  
end

def find\_trashed  
find(all, :conditions =\> [‘trashed = 1’])  
end

---

<div class="post-metadata">

**Author:** ![PeteSalty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bc79bd/32.png) [@PeteSalty](https://www.ruby-forum.com/u/PeteSalty)\
**Post date:** [March 14, 2007, 8:52pm UTC](https://www.ruby-forum.com/t/how-to-filter-find-all/88774/6 "2007-03-14T20:52:07Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![PeteSalty](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bc79bd/32.png) [@PeteSalty](https://www.ruby-forum.com/u/PeteSalty)\
**Post date:** [March 16, 2007, 2:09pm UTC](https://www.ruby-forum.com/t/how-to-filter-find-all/88774/7 "2007-03-16T14:09:17Z")

</div>

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
