valibuk.net

A place for opinions and notes of a valibuk.

Various Number of Conditions

Tagged with: — ondrej at 1:49 am on Monday, August 21, 2006

Ruby on RailsFiltering is basically about writing conditions. In most cases the number of conditions is fixed, e.g. an internal filter in an application. Then it is quite easy to prepare a value for the conditions parameter.

But what to do if a number of conditions may vary? It is not a good idea to pass an empty value, because an empty value is still a valid value. We have to somehow implicitly say that a condition with an empty value should not be taken into a filtering process at all.

One option is to create a complicated condition that will distinguish between an empty value and a meaningful value, e.g.

  1. AND ((? == "") OR (city LIKE ?)) AND

or another option is to improve creating of a value of the conditions parameter.

Let’s assume our filter consists of two fields: first_name and last_name. A conditions value is computed in a controller:

  1. conditions_text = []
  2. conditions_params = []
  3.  
  4. if @params[:first_name]
  5.   conditions_text << "first_name ILIKE ?"
  6.   conditions_params << "%#{@params[:first_name]}%"
  7. end
  8. if @params[:last_name]
  9.   conditions_text << "last_name ILIKE ?"
  10.   conditions_params << "%#{@params[:last_name]}%"
  11. end
  12.  
  13. conditions = conditions_text.empty? ?
  14.   nil : [conditions_text.join(" and "), *conditions_params]
  15.  
  16. @total = User.count(:conditions => conditions)
  17. @user_pages, @users = paginate :users,
  18.   :conditions => conditions,
  19.   :per_page => 10

Lines 1-2 initialise two variables - conditions_text for condition definitions and conditions_params for parameters.

Lines 4-7 and 8-11 contain a definition of two parameters. They are added only if a value of the corresponding filter form fields is not empty.

The magic is on lines 13 and 14. If a value of the conditions_text is empty then a nil value is used as the condition, i.e. filtering is not active. Otherwise a value of the condition parameter is constructed — it is a pair definition–parameters.
A definition value, a string, is created by joing all particular definitions with the AND keyword (with two spaces).
A parameters value is created by converting a list to an array.

Lines 16-19 show an example how to use the generated value (I use it for an AJAX filtering).

Conclusion

The proposed solution works only with only-AND or only-OR conditions — what is in most cases enough.
To really solve this, It is possible to have two (AND, OR) sets of definitions and parameters and put them together at the end… but it is quite cumbersome. Is there a better solution?

Thanks to Viktor for help with the *conditions_params code.

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • DZone
  • Digg
  • Reddit
  • Technorati
  • Furl
  • NewsVine
  • Slashdot
  • Ma.gnolia
  • StumbleUpon

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Comment Preview


commercial break :)

Make an account on slicehost.com -- a really good hosting where you have your own virtual machine. I installed Gentoo there = I like it very much ;)