This page contains automated test results for code from O'Reilly's Ruby Cookbook. If this code looks interesting or useful, you might want to buy the whole book.
Building Queries Programmatically | ||
---|---|---|
Code | Expected | Actual |
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 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!" |
Error! (Exception?) Here's stdout: TypeError: singleton method called for a different object from /usr/lib/ruby/gems/1.8/gems/facets_more-1.0.2/lib/facet/basicobject.rb:96:in `bind' from /usr/lib/ruby/gems/1.8/gems/facets_more-1.0.2/lib/facet/basicobject.rb:96:in `method_added' from /usr/lib/ruby/gems/1.8/gems/facets_more-1.0.2/lib/facet/basicobject.rb:95 from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:21:in `require' from /usr/lib/ruby/gems/1.8/gems/activesupport-1.3.0/lib/active_support/dependencies.rb:136:in `require' from /usr/lib/ruby/gems/1.8/gems/facets_more-1.0.2/lib/facet/openobject.rb:51 from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:21:in `require' from /usr/lib/ruby/gems/1.8/gems/activesupport-1.3.0/lib/active_support/dependencies.rb:136:in `require' from /usr/lib/ruby/gems/1.8/gems/facets_more-1.0.2/lib/facet/annotation.rb:53 from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:21:in `require' from /usr/lib/ruby/gems/1.8/gems/activesupport-1.3.0/lib/active_support/dependencies.rb:136:in `require' from /usr/lib/ruby/gems/1.8/gems/glue-0.28.0/lib/glue/property.rb:1 from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:21:in `require' from /usr/lib/ruby/gems/1.8/gems/activesupport-1.3.0/lib/active_support/dependencies.rb:136:in `require' from /usr/lib/ruby/gems/1.8/gems/glue-0.28.0/lib/glue.rb:18 from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:21:in `require' from /usr/lib/ruby/gems/1.8/gems/activesupport-1.3.0/lib/active_support/dependencies.rb:136:in `require' from /usr/lib/ruby/gems/1.8/gems/og-0.28.0/lib/og.rb:14 from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require' from /usr/lib/ruby/gems/1.8/gems/activesupport-1.3.0/lib/active_support/dependencies.rb:136:in `require' from ./cookbook_dbconnect.rb:5 from (irb):1NameError: undefined local variable or method `activerecord_connect' for #<Object:0xb7d66970> from (irb):14 ActiveRecord::ConnectionNotEstablished: ActiveRecord::ConnectionNotEstablished from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:225:in `retrieve_connection' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:78:in `connection' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:696:in `columns' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:1963:in `attributes_from_column_definition' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:1347:in `initialize_without_callbacks' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/callbacks.rb:236:in `initialize' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:406:in `create' from (irb):17 ActiveRecord::ConnectionNotEstablished: ActiveRecord::ConnectionNotEstablished from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:225:in `retrieve_connection' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:78:in `connection' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:696:in `columns' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:1963:in `attributes_from_column_definition' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:1347:in `initialize_without_callbacks' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/callbacks.rb:236:in `initialize' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:406:in `create' from (irb):19 ActiveRecord::ConnectionNotEstablished: ActiveRecord::ConnectionNotEstablished from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:225:in `retrieve_connection' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:78:in `connection' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:1299:in `quote_bound_value' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:1299:in `quote_bound_value' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:1283:in `replace_bind_variables' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:1283:in `replace_bind_variables' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:1272:in `sanitize_sql' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:1056:in `add_conditions!' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:1012:in `construct_finder_sql' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:924:in `find_every' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:918:in `find_initial' from /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:380:in `find' from (irb):11:in `find_by_map' from (irb):21 |
class Criteria < Hash def initialize(values) values.each { |k,v| add(k, *v) } @or_criteria = nil @and_criteria = nil end :private attr_accessor :or_criteria, :and_criteria :public def add(field, value, operation='=') self[field] = [value, operation] end def or(criteria) c = self while c.or_criteria != nil break if c == criteria c = c.or_criteria end c.or_criteria = criteria return self end def and(criteria) c = self while c.and_criteria != nil break if c == criteria c = c.and_criteria end c.and_criteria = criteria return self end class Criteria def to_where_clause sql = [] values = [] each do |field, value| if value.respond_to? :to_str value, operation = value, '=' else value, operation = value[0..1] end sql << "#{field} #{operation} ?" values << value end sql = '(' + sql.join(' AND ') + ')' if or_criteria or_where = or_criteria.to_where_clause sql = "(#{sql} OR #{or_where.shift})" values += or_where end if and_criteria and_where = and_criteria.to_where_clause sql = "(#{sql} AND #{and_where.shift})" values += and_where end return values.unshift(sql) end end class ActiveRecord::Base def self.find_by_criteria(id, criteria, args={}.freeze) args = args.dup args[:conditions] = criteria.to_where_clause find(id, args) end end review = Criteria.new(:title => ['%Review%', 'LIKE']) bad_movie = Criteria.new(:title => ["%Movie%", 'LIKE'], :content => 'Zero stars!') good_game = Criteria.new(:title => ['%Game%', 'LIKE'], :content => 'Four stars!') no_cricket = Criteria.new(:title => ['%Cricket%', 'NOT LIKE']) review.and(bad_movie.or(good_game)).and(no_cricket) review.to_where_clause |
["((title LIKE ?) AND |
Error! (Exception?) Here's stdout: |
BlogPost.find_by_criteria(:all, review).each { |post| puts post.title } |
Game Review: Foosball Carnage Movie Review: Foosball Carnage: The Movie Just an idea... |
Error! (Exception?) Here's stdout: |
order_by = [[:title, 'ASC']] |
... |