conditioner for ActiveRecord-friendly conditions from a collection

I frequently have a collection of values that I want to match in an ActiveRecord query, but it would be nice if I could let ActiveRecord handle checking the data and escaping it properly. So, I wrote this method to return ActiveRecord-friendly conditions, such as:
["user_id=? AND job_id=?", 3, 4]
based on the ‘raw’ conditions you feed to it, such as:
[['user_id', 3], ['job_id', 4]]

# Returns ActiveRecord-friendly conditions based on the given
# raw conditions; handles grouping based on like field names;
# allows different boolean operators in raw conditions;
# allows different comparison operators in raw conditions;
# raw conditions setup:
# [[field name, desired value, bool. op., comp. op.], ...]
# raw conditions example:
# [['type_id', '4', 'OR'], ['created_on', Date.new, 'AND', '<=']]
def conditioner( raw_conditions )
  conditions = ["("]
  count = 0
  prev_name = raw_conditions[0][0]
  raw_conditions.each do |condition|
    name = condition[0]
    value = condition[1]
      
    if condition[2]
      bool_type = condition[2]
    else
      bool_type = 'OR'
    end
      
    if condition[3]
      comparison = condition[3]
    else
      comparison = '='
    end
      
    conditions[0] << ') AND ' if prev_name != name
    conditions[0] << ' ' << bool_type.to_s << ' ' unless count == 0 || prev_name != name
    conditions[0] << '(' if prev_name != name
    conditions[0] << "#{name} #{comparison} ?"
      
    conditions << value
      
    prev_name = name
    count += 1
  end
  conditions[0] << ')'

  conditions
end

This way, you can do something like the following:
model_ids = Model.find( :all ).map( &:id )
raw_conditions = model_ids.collect { |id| ['model_id', id] }
conditions = conditioner( raw_conditions )
desired_collection = OtherModel.find( :all, :conditions => conditions )

This entry was cross-posted to my Code Snippets page.

This entry was posted in Programming and tagged , , | Current music Hung Up by Madonna. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

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