select_extra_columns 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.markdown +8 -3
- data/README.markdown +20 -8
- data/lib/select_extra_columns.rb +47 -18
- metadata +3 -3
data/CHANGELOG.markdown
CHANGED
@@ -1,12 +1,17 @@
|
|
1
|
-
2010-
|
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-
|
10
|
+
2010-03-09
|
6
11
|
==========
|
7
12
|
* Changed cloning to inheritance.
|
8
13
|
|
9
|
-
2010-
|
14
|
+
2010-03-09
|
10
15
|
==========
|
11
16
|
* Added stricter validation for :extra_columns input.
|
12
17
|
|
data/README.markdown
CHANGED
@@ -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.
|
131
|
-
|
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
|
-
|
147
|
-
users = User.
|
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
|
data/lib/select_extra_columns.rb
CHANGED
@@ -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
|
19
|
-
|
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
|
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
|
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
|
-
|
39
|
-
|
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
|
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
|
-
-
|
9
|
-
version: 0.0.
|
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-
|
17
|
+
date: 2010-03-11 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|