Wednesday, November 17, 2010

Rails 2.3 named scope awesomeness

Although sadly named scopes are not the same in Rails 3 according to some.
I love to use them in the rails 2.3 apps that I still maintain and support.
most importantly in conjunction with a plugin/gem called searchlogic the potential for named scope has no limit in being awesome.

Though there are too many tutorials, screen casts etc for these, a recent use I uncovered in fixing a minor issue I had with a search form in my application really moved me, that is why this post.

It is already known that named scopes can be given lambda arguments to for dynamic queries on a table like

named_scope :of_size, lambda {|size|{:conditions => {:size => size}}}

so for two parameters I would have to do something like

named_scope :made_between, lambda{|from,to|
{:conditions => ["mfg_date between to_date (?, 'mm-dd-yyyy') and to_date (?, 'mm-dd-yyyy')",from, to]}
}

how searchlogic fits into this is that, searchlogic uses named_scopes to create search object and finally creating the query we want to get a particular subset of rows from a table.

so things like

Product.description_like = "abc"
Product.mfg_date_gt = "10-2-2010"

You get the picture. And this can be passed on through views by having the fields with those named scope names and it will work like charm.
Back to issue I was facing , there is no clean way of sending two parameters to the same named scope without some ugly confusing hack or a condition in controller to deal with these separately than the clean DRY @object.search(params[:search]), so instead I sent a hash and it worked like a charm.

named_scope :made_between, lambda{|manufactured_date|
{:conditions => ["mfg_date between to_date (?, 'mm-dd-yyyy') and to_date (?, 'mm-dd-yyyy')", manufactured_date[:from], manufactured_date[:to]]}
}

though this is not a very useful post as in not a step by step tutorial, I hope this helps in getting a good insight in trying out things in context of keeping your controllers thin and code DRY.


No comments:

Post a Comment