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.
- 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
|
|