What if you need to call a custom query in Rails? In most cases you'll be content with ditching ActiveRecord::Base.find and going with .find_by_sql. But instantiating an Active Record per row is expensive. What if you want something faster, but you still want an OO feel? Pop this in your environment.rb (or a separate file) and give this a whirl:
1
2
3 require 'ostruct'
4 module ActiveRecord
5 class Base
6 class << self
7 def select_all(query)
8 rows = connection.select_all(query)
9 rows.map! do |row|
10 row = OpenStruct.new(row)
11 table = row.send(:table)
12 table.each {|k, v| table[k] = select_type_cast(v) }
13 row
14 end
15 rows
16 end
17 def select_one(query)
18 select_all(query).first
19 end
20 def select_value(query)
21 select_type_cast(connection.select_value(query))
22 end
23 def select_type_cast(v)
24 return unless v
25 if md = v.match(/^(\d{4})-(\d{2})-(\d{2})$/)
26 Date.new(*md.captures.map(&:to_i)) rescue v
27 elsif md = v.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/)
28 Time.local(*md.captures.map(&:to_i)) rescue v
29 elsif v =~ /^\d+$/
30 v.to_i
31 elsif v =~ /^\d+(?:\.\d+)+$/
32 v.to_f
33 else
34 v
35 end
36 end
37 end
38 end
39 end