# Selecting a subset of a table with DRY

**URL:** <https://www.ruby-forum.com/t/selecting-a-subset-of-a-table-with-dry/52001>\
**Category:** Rails\
**Created:** [January 10, 2006, 12:08am UTC](https://www.ruby-forum.com/t/selecting-a-subset-of-a-table-with-dry/52001 "2006-01-10T00:08:04Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![vann](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/eada6e/32.png) [@vann](https://www.ruby-forum.com/u/vann)\
**Post date:** [January 10, 2006, 12:08am UTC](https://www.ruby-forum.com/t/selecting-a-subset-of-a-table-with-dry/52001/1 "2006-01-10T00:08:04Z")

</div>

Hello,

I have table called ‘listings.’ There are a certain combination of  
properties which make a listing viewable (e.g., it is confirmed, has  
been authorized, hasn’t expired, etc.). Each listing has one and only  
one category.

I want to be able to do things like Listing.find\_viewable(…) and  
Category.find(…).viewable\_listings, but I see no way to do this  
without violating DRY in several places, or stepping all over AR’s toes.

My idea was to define a method in application.rb which returns the  
appropriate SQL string that makes a listing viewable, call it  
viewable\_sql, and then put that where appropriate. However, I’d like  
find\_viewable to work just like find, except that it would modify the  
parameters to find to incorporate those conditions.

Any thoughts or examples of something similar?

Thanks.

–  
Jesse F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
University of Chicago - NSIT Web Services  
AIM: farmerje  
Jabber: removed\_email\_address@domain.invalid  
Phone: (773)363-1058

---

<div class="post-metadata">

**Author:** ![vann](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/eada6e/32.png) [@vann](https://www.ruby-forum.com/u/vann)\
**Post date:** [January 10, 2006, 1:29am UTC](https://www.ruby-forum.com/t/selecting-a-subset-of-a-table-with-dry/52001/2 "2006-01-10T01:29:35Z")

</div>

Hello Jesse,

2006/1/9, Jesse F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> My idea was to define a method in application.rb which returns the  
> appropriate SQL string that makes a listing viewable, call it  
> viewable\_sql, and then put that where appropriate. However, I’d like  
> find\_viewable to work just like find, except that it would modify the  
> parameters to find to incorporate those conditions.

Did you know that class methods of model objects are made available in  
has\_many/belongs\_to and friends ?

So, if you do

class Listing  
def self.viewables(options={})  
options.merge(:conditions =\> [‘confirmed = 1 AND authorized = 1’])  
self.find(:all, options)  
end  
end

Then, you can do

Category.listings.viewables(:order =\> ‘created\_at DESC’)

Hope that helps !

---

<div class="post-metadata">

**Author:** ![vann](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/eada6e/32.png) [@vann](https://www.ruby-forum.com/u/vann)\
**Post date:** [January 10, 2006, 1:56am UTC](https://www.ruby-forum.com/t/selecting-a-subset-of-a-table-with-dry/52001/3 "2006-01-10T01:56:42Z")

</div>

Francois B. wrote:

> end
> 
> Then, you can do
> 
> Category.listings.viewables(:order =\> ‘created\_at DESC’)
> 
> ## Hope that helps !
> 
> FranÃ§ois Beausoleil  
> [http://blog.teksol.info/](http://blog.teksol.info/)

That is nice. For the like I was defining has\_many :viewable\_listings  
and then doing Category.find(some\_category).viewable\_listings. This  
provides another nice perspective.

However, this doesn’t entirely solve my problem. It is two-fold, I  
guess.

1. Sometimes I want to find a specific viewable listing.
2. Sometimes I want to find all viewable listings satisfying certain  
criteria.

The way I have it now is that basically the “is\_viewable?” sort of logic  
is duplicated for each of these. This will simplify my error handling  
since the controllers searching for a specific entry will be expecting  
an exception to be raised if there is an error, while ones requesting  
multiple entries will expect the returned result to be false.

So, for example, I might do this:  
def view  
@listing = Listing.find\_viewable(params[:id])  
rescue  
…  
end

while elsewhere I might want

def category  
@listings = Category.find\_by\_name(params[:name]).viewable\_listings  
unless @listings  
…  
end  
end

or some such. Is there any way I can integrate these two things without  
breaking AR and maintaining DRY? The logic is replicated once in  
viewable\_listings or equivalent and once in find\_viewable.

Thanks again!

–  
Jesse F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
University of Chicago - NSIT Web Services  
AIM: farmerje  
Jabber: removed\_email\_address@domain.invalid  
Phone: (773)363-1058

---

<div class="post-metadata">

**Author:** ![vann](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/eada6e/32.png) [@vann](https://www.ruby-forum.com/u/vann)\
**Post date:** [January 10, 2006, 3:09pm UTC](https://www.ruby-forum.com/t/selecting-a-subset-of-a-table-with-dry/52001/4 "2006-01-10T15:09:03Z")

</div>

— quote —  
Is there any way I can integrate these two things without  
breaking AR and maintaining DRY? The logic is replicated once in  
viewable\_listings or equivalent and once in find\_viewable.  
— quote —

so just to make sure i understand this correctly, you want a single  
method  
to be able to return either a single viewable listing or multiple  
viewable  
listings depending on the argiments? sounds just like what  
AR::Base.finddoes for you already, for the most part.

if you think about it, you’d basically be rewriting AR::Base.find with  
hardcoded conditions (whatever makes a listing ‘viewable’). all this  
would  
do is save you from having to specify your conditions in the find call.

if you step back and think about it for a minute, this is the way you  
would  
normally do it.

def view  
begin  
@viewable\_listing = Listing.find(params[:id], :conditions =\> “…”)  
rescue RecordNotFound  
# handle record not found exception here  
end  
end

def category  
@viewable\_listings = Category.listings.find(:all, :conditions =\>  
“…”)  
end

with your idea, you want to be able to do:

def view  
begin  
@viewable\_listing = Listing.find\_viewable(params[:id])  
rescue RecordNotFound  
# handle record not found exception  
end  
end

def category  
@viewable\_listings = Category.listings.find\_viewable(:all)  
end

notice the only thing i’ve changed is the method name and removed the  
:conditions, as the conditions would be handled within your custom  
find\_viewable method

class Listing \< ActiveRecord::Base  
def self.find\_viewable(args)  
conditions = “…”  
# merge in your custom ‘viewable’ conditions into the arguments and  
then  
call AR::Base.find  
self.find(args)  
end  
end

merging your custom conditions is beyond my abilities at the moment, but  
i  
think this is what you are after. you could probably take a look at the  
source to AR::Base.find to figure it out.

hope this helps.
