select_extra_columns 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,17 @@
1
- 2010-04-11
1
+ 2010-03-11
2
+ ==========
3
+ * Added support for `find_by_sql`.
4
+ * Exposed `find_extra_columns_class` method.
5
+
6
+ 2010-03-10
2
7
  ==========
3
8
  * Added support for sharing `extra_columns` definition across finders
4
9
 
5
- 2010-04-09
10
+ 2010-03-09
6
11
  ==========
7
12
  * Changed cloning to inheritance.
8
13
 
9
- 2010-04-09
14
+ 2010-03-09
10
15
  ==========
11
16
  * Added stricter validation for :extra_columns input.
12
17
 
@@ -60,7 +60,16 @@ Getting Started
60
60
  users.first.street # returns the street
61
61
  users.first.active # returns true/false
62
62
 
63
-
63
+ users = User.find_by_sql("SELECT A.*, count(B.id) as post_count
64
+ FROM users A, posts B
65
+ WHERE A.id = B.user_id AND B.ptype = 'public'
66
+ GROUP BY A.id
67
+ UNION
68
+ SELECT A.*, count(B.id) as post_count
69
+ FROM users A, customer_posts B
70
+ WHERE A.id = B.user_id AND B.ptype = 'private'
71
+ GROUP BY A.id",
72
+ :extra_columns => :post_count)
64
73
  Dynamically added column fields are read only. Any value set to these fields are ignored during save.
65
74
 
66
75
  user = User.first(:joins => :address, :select => "*, addresses.street as street",
@@ -127,12 +136,12 @@ You can declare the extra columns in your model and use them across finders
127
136
 
128
137
  Now `:user_info` and `:post_info` can be used in finders.
129
138
 
130
- users = User.find(:all, :joins => :posts, :select => "users.*, count(posts.id) as post_count, max(posts.created_at) as last_post_at",
131
- :extra_columns => :post_info)
132
-
133
- user = User.first(:joins => :address, :select => "users.*, addresses.street as street, addresses.city as city",
134
- :extra_columns => :address_info )
139
+ users = User.all(:joins => :posts, :extra_columns => :post_info
140
+ :select => "users.*, count(posts.id) as post_count, max(posts.created_at) as last_post_at")
135
141
 
142
+ user = User.first(:joins => :address, :extra_columns => :address_info,
143
+ :select => "users.*, addresses.street as street, addresses.city as city")
144
+
136
145
  ## Naming conflicts
137
146
  When a symbol/string is passed as input to `:extra_columns` option, the finder uses cached `extra_columns` definition by the given name.
138
147
  If no definition is found, then finder creates a new `extra_columns` definition with the input as a column.
@@ -143,10 +152,13 @@ If no definition is found, then finder creates a new `extra_columns` definition
143
152
  extra_columns :post_count, [:post_count, :integer], :last_post_at => :datetime
144
153
  end
145
154
 
146
- The finder call below, `post_count` maps on to a column in the select list and a `extra_columns` definition. Finder chooses the `extra_columns` definition.
147
- users = User.find(:all, :joins => :posts, :select => "users.*, count(posts.id) as post_count, max(posts.created_at) as last_post_at",
155
+ In the `finder` call below, `post_count` maps on to a column name and a `extra_columns` definition name. Finder chooses the `extra_columns` definition.
156
+ users = User.all(:joins => :posts, :select => "users.*, count(posts.id) as post_count, max(posts.created_at) as last_post_at",
148
157
  :extra_columns => :post_count)
149
158
 
159
+ ## Accessing the extra column model
160
+ The gem creates and caches a model for every unique `extra_column` configuration. This model can be accessed using the `find_extra_columns_class` method.
161
+ User.find_extra_columns_class(:post_count).find_by_sql("")
150
162
 
151
163
  ## Valid data types for column fields in `:extra_columns`
152
164
  :binary
@@ -5,38 +5,71 @@ module SelectExtraColumns
5
5
  end
6
6
 
7
7
  module ClassMethods
8
- def self.extended(active_record_class)
8
+ def self.extended(active_record_class) #:nodoc:
9
9
  class << active_record_class
10
10
  alias_method_chain :find_every, :extra_columns
11
+ alias_method_chain :find_by_sql,:extra_columns
11
12
  end
12
13
  active_record_class.class_inheritable_array(:klasses_with_extra_columns)
13
14
  active_record_class.klasses_with_extra_columns ||= []
14
15
  end
15
16
 
16
- def find_every_with_extra_columns options
17
+ def find_every_with_extra_columns options #:nodoc:
17
18
  extra_columns = options.delete(:extra_columns)
18
- return find_every_without_extra_columns options if extra_columns.nil?
19
- klass_with_extra_columns(extra_columns).send(:find_every, options)
19
+ return find_every_without_extra_columns(options) if extra_columns.nil?
20
+ find_or_create_extra_columns_class(extra_columns).send(:find_every, options)
20
21
  end
21
22
 
22
- def validate_find_options(options)
23
+ def find_by_sql_with_extra_columns sql, options={}
24
+ extra_columns = options.delete(:extra_columns)
25
+ return find_by_sql_without_extra_columns(sql) if extra_columns.nil?
26
+ find_or_create_extra_columns_class(extra_columns).send(:find_by_sql, sql)
27
+ end
28
+
29
+ def validate_find_options(options) #:nodoc:
23
30
  extra_columns = options.delete(:extra_columns)
24
31
  super
25
32
  ensure
26
33
  options[:extra_columns]= extra_columns if extra_columns
27
34
  end
28
35
 
29
- def klass_with_extra_columns extra_columns
36
+ def find_or_create_extra_columns_class extra_columns #:nodoc:
30
37
  # look for the class in the cache.
31
- (
32
- [String, Symbol].include?(extra_columns.class) ?
33
- self.klasses_with_extra_columns.find{|k| k.extra_columns_key == extra_columns.to_s} :
34
- self.klasses_with_extra_columns.find{|k| k.extra_columns == extra_columns}
35
- ) or extra_columns_class(extra_columns)
38
+ find_extra_columns_class(extra_columns) || create_extra_columns_class(extra_columns)
36
39
  end
37
40
 
38
- def extra_columns_class extra_columns, extra_columns_key=nil
39
- extra_column_definitions = prepare_extra_column_definitions(extra_columns)
41
+ # Returns cached extra_column model. The argument can take two forms:
42
+ #
43
+ # * extra_column key - Key used to register the model using the call to extra_columns
44
+ # * extra_column key - Definition used in a prior query.
45
+ #
46
+ # ==== Examples
47
+ # class Person < ActiveRecord::Base
48
+ # select_extra_column
49
+ # extra_column :address_info, :street, :city, :zip
50
+ # end
51
+ # klass = Person.find_extra_columns_class(:address_info)
52
+ # Person.find(:joins => :address, :select => "people.*, addresses.street, addresses.city, addresses.zip",
53
+ # :extra_columns = [:street, :city, :zip])
54
+ # ...
55
+ # ...
56
+ # klass = Person.find_extra_columns_class([:street, :city, :zip])
57
+ # klass.find_by_sql("..")
58
+ def find_extra_columns_class extra_columns
59
+ # look for the class in the cache.
60
+ [String, Symbol].include?(extra_columns.class) ?
61
+ self.klasses_with_extra_columns.find{|k| k.extra_columns_key == extra_columns.to_s} :
62
+ self.klasses_with_extra_columns.find{|k| k.extra_columns == extra_columns}
63
+ end
64
+
65
+ # Creates and caches an extra_column model.
66
+ #
67
+ def extra_columns extra_columns_key, *args
68
+ create_extra_columns_class args.concat(args.extract_options!.to_a), extra_columns_key
69
+ end
70
+
71
+ def create_extra_columns_class extra_columns, extra_columns_key=nil #:nodoc:
72
+ extra_column_definitions = create_extra_columns(extra_columns)
40
73
  return self if extra_column_definitions.empty?
41
74
  read_only_attrs = extra_column_definitions.collect{|cd| ":#{cd.name}" }.join(",")
42
75
  klass_name = "#{self.name}#{Time.now.to_i}#{extra_columns.hash.abs}"
@@ -57,11 +90,7 @@ module SelectExtraColumns
57
90
  end
58
91
  end
59
92
 
60
- def extra_columns extra_columns_key, *args
61
- extra_columns_class args.concat(args.extract_options!.to_a), extra_columns_key
62
- end
63
-
64
- def prepare_extra_column_definitions extra_columns
93
+ def create_extra_columns extra_columns #:nodoc:
65
94
  extra_columns = [extra_columns] if extra_columns.is_a?(Symbol) or extra_columns.is_a?(String)
66
95
  extra_columns = extra_columns.to_a if extra_columns.is_a?(Hash)
67
96
  return [] unless extra_columns.is_a?(Array)
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 6
9
- version: 0.0.6
8
+ - 7
9
+ version: 0.0.7
10
10
  platform: ruby
11
11
  authors:
12
12
  - Kandada Boggu
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-10 00:00:00 -08:00
17
+ date: 2010-03-11 00:00:00 -08:00
18
18
  default_executable:
19
19
  dependencies: []
20
20