<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: conditions code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Fri, 08 Aug 2008 19:50:34 GMT</pubDate>
    <description>DZone Snippets: conditions code</description>
    <item>
      <title>conditioner for ActiveRecord-friendly conditions from a collection</title>
      <link>http://snippets.dzone.com/posts/show/2510</link>
      <description>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: &lt;code&gt;["user_id=? AND job_id=?", 3, 4]&lt;/code&gt; based on the 'raw' conditions you feed to it, such as: &lt;code&gt;[['user_id', 3], ['job_id', 4]]&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# Returns ActiveRecord-friendly conditions based on the given&lt;br /&gt;# raw conditions; handles grouping based on like field names;&lt;br /&gt;# allows different boolean operators in raw conditions;&lt;br /&gt;# allows different comparison operators in raw conditions;&lt;br /&gt;# raw conditions setup:&lt;br /&gt;# [[field name, desired value, bool. op., comp. op.], ...]&lt;br /&gt;# name = condition[0]&lt;br /&gt;# value = condition[1]&lt;br /&gt;# bool_type = condition[2]&lt;br /&gt;# comparison = condition[3]&lt;br /&gt;# raw conditions example:&lt;br /&gt;# [['type_id', '4', 'OR'], ['created_on', Date.new, 'AND', '&lt;=']]&lt;br /&gt;def conditioner( raw_conditions )&lt;br /&gt;  return nil if raw_conditions.nil? || raw_conditions.empty?&lt;br /&gt;  &lt;br /&gt;  conditions = ['(']&lt;br /&gt;  count = 0&lt;br /&gt;  prev_name = raw_conditions[0][0]&lt;br /&gt;  raw_conditions.each do |condition|&lt;br /&gt;    name = condition[0]&lt;br /&gt;      &lt;br /&gt;    conditions[0] &lt;&lt; ') AND ' if prev_name != name&lt;br /&gt;    conditions[0] &lt;&lt; ' ' &lt;&lt; ( condition[2] || 'OR' ) &lt;&lt; ' ' unless count == 0 || prev_name != name&lt;br /&gt;    conditions[0] &lt;&lt; '(' if prev_name != name&lt;br /&gt;    conditions[0] &lt;&lt; name + ' ' &lt;&lt; ( condition[3] || '=' ) + ' ?'&lt;br /&gt;      &lt;br /&gt;    conditions &lt;&lt; condition[1]&lt;br /&gt;      &lt;br /&gt;    prev_name = name&lt;br /&gt;    count += 1&lt;br /&gt;  end&lt;br /&gt;  conditions[0] &lt;&lt; ')'&lt;br /&gt;&lt;br /&gt;  conditions&lt;br /&gt;end&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This way, you can do something like the following:&lt;br /&gt;&lt;code&gt;model_ids = Model.find( :all ).map( &amp;:id )&lt;br /&gt;raw_conditions = model_ids.collect { |id| ['model_id', id] }&lt;br /&gt;conditions = conditioner( raw_conditions )&lt;br /&gt;desired_collection = OtherModel.find( :all, :conditions =&gt; conditions )&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If your query needs to depend on more than one factor, you might do something like the following:&lt;br /&gt;&lt;code&gt;if test&lt;br /&gt;  raw_conditions = [['user_id', 3]]&lt;br /&gt;else&lt;br /&gt;  raw_conditions = [['user_id', 4], ['groups.name', 'dev']]&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;team_ids.each { |id| raw_conditions &lt;&lt; ['team_id', id, 'AND'] }&lt;/code&gt;</description>
      <pubDate>Thu, 31 Aug 2006 22:02:52 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2510</guid>
      <author>moneypenny ()</author>
    </item>
  </channel>
</rss>
