O'Reilly logo

Ruby Cookbook by Leonard Richardson, Lucas Carlson

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

13.13. Building Queries Programmatically

Problem

You have to write fragments of SQL to pass parameters into an ActiveRecord query. You'd like to dispense with SQL altogether, and represent the query paramaters as a Ruby data structure.

Solution

Here's a simple solution. The method ActiveRecord::Base.find_by_map defined below picks up where find leaves off. Normally a query is represented by a SQL fragment, passed in as the :conditions argument. Here, the :conditions argument contains a mapping of database field names to the desired values:

	require 'cookbook_dbconnect'

	class ActiveRecord::Base
	  def self.find_by_map(id, args={}.freeze)
	    sql = []
	    values = []
	    args[:conditions].each do |field, value|
	      sql << "#{field} = ?"
	      values << value
	    end if args[:conditions]
	    args[:conditions] = [sql.join(' AND '), values]
	    find(id, args)
	  end
	end

Here's find_by_map in action, using the BlogPost class first seen in Recipe 13.11:

	activerecord_connect

	class BlogPost < ActiveRecord::Base
	end

	BlogPost.create(:title => 'Game Review: Foosball Carnage',
	                :content => 'Four stars!')
	BlogPost.create(:title => 'Movie Review: Foosball Carnage: The Movie',
	                :content => 'Zero stars!')

	BlogPost.find_by_map(:first,
	                     :conditions => {:title =>
	                                     'Game Review: Foosball Carnage' }
	                    ).content
	# => "Four stars!"

Discussion

ActiveRecord saves you from having to write a lot of SQL, but you still have to write out the equivalent of a SQL WHERE clause every time you call ActiveRecord::Base#find. The find_by_map method lets you define those ...

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required