DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone >

Conditioner For ActiveRecord-friendly Conditions From A Collection

Snippets Manager user avatar by
Snippets Manager
·
Aug. 31, 06 · · Code Snippet
Like (0)
Save
Tweet
529 Views

Join the DZone community and get the full member experience.

Join For Free
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.], ...]
# name = condition[0]
# value = condition[1]
# bool_type = condition[2]
# comparison = condition[3]
# raw conditions example:
# [['type_id', '4', 'OR'], ['created_on', Date.new, 'AND', '<=']]
def conditioner( raw_conditions )
  return nil if raw_conditions.nil? || raw_conditions.empty?
  
  conditions = ['(']
  count = 0
  prev_name = raw_conditions[0][0]
  raw_conditions.each do |condition|
    name = condition[0]
      
    conditions[0] << ') AND ' if prev_name != name
    conditions[0] << ' ' << ( condition[2] || 'OR' ) << ' ' unless count == 0 || prev_name != name
    conditions[0] << '(' if prev_name != name
    conditions[0] << name + ' ' << ( condition[3] || '=' ) + ' ?'
      
    conditions << condition[1]
      
    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 )

If your query needs to depend on more than one factor, you might do something like the following:
if test
  raw_conditions = [['user_id', 3]]
else
  raw_conditions = [['user_id', 4], ['groups.name', 'dev']]
end

team_ids.each { |id| raw_conditions << ['team_id', id, 'AND'] }

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Is Java Still Relevant?
  • 10 Steps to Become an Outstanding Java Developer
  • 6 Things Startups Can Do to Avoid Tech Debt
  • How to Generate Fake Test Data

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo