Stanish
Stanish

Reputation: 145

How can I get an ActiveRecord query to ignore nil conditions?

In order to avoid having to construct complicated dynamic SQL queries, I'd like to be able to just pass in nil values in my conditions, and have those ignored. Is that supported by ActiveRecord?

Here is an example.

event = Event.find(:all, :conditions => { 
                                          :title       => params[:title],
                                          :start_time  => params[:start_time], 
                                          :end_time    => params[:end_time]
                                        }).first

In that particular case, if params[:start_time] is set to nil, ActiveRecord will search for those Events that have their start_time set to null. Instead, I'd like it to just ignore start_time. How do I do that?

Upvotes: 3

Views: 2346

Answers (1)

Jim
Jim

Reputation: 475

You don't have to "create complicated dynamic SQL queries" to do what you need. Simply construct your conditions hash separately, and either exclude the null values at the time of creation or after you've created the hash.

conditions = {}
conditions[:title] = params[:title] unless params[:title].blank?
conditions[:start_time] = params[:start_time] unless params[:start_time].blank?
conditions[:end_time] = params[:end_time] unless params[:end_time].blank?

or

conditions = {:title => params[:title], :start_time => params[:start_time], :end_time => params[:end_time]}
conditions.delete_if {|k,v| v.blank? }

or

conditions = params.reject {|k,v| !([:title, :start_time, :end_time]).include?(k) }

but that last form will only work if the keys are actually symbols. In Rails the params hash is a HashWithIndifferentAccess which allows you to access the text keys as symbols. Of course you could just use the text values in your array of keys to include if necessary.

and then query with your pre-built conditions hash:

event = Event.find(:all, :conditions => conditions).first

Upvotes: 6

Related Questions