acts-as-joinable 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/acts-as-joinable.rb +10 -0
- data/lib/acts_as_joinable/active_record_patch.rb +17 -9
- metadata +4 -4
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
|
|
5
5
|
spec = Gem::Specification.new do |s|
|
6
6
|
s.name = "acts-as-joinable"
|
7
7
|
s.authors = ["Lance Pollard"]
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.4"
|
9
9
|
s.summary = "ActsAsJoinable: DRYing up Many-to-Many Relationships in ActiveRecord"
|
10
10
|
s.homepage = "http://github.com/viatropos/acts-as-joinable"
|
11
11
|
s.email = "lancejpollard@gmail.com"
|
data/lib/acts-as-joinable.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# https://rails.lighthouseapp.com/projects/8994/tickets/5182-activerecordcalculations-returns-incorrect-data-when-grouping-by-multiple-fields
|
1
2
|
module ActsAsJoinable
|
2
3
|
|
3
4
|
def self.models
|
@@ -44,6 +45,15 @@ module ActsAsJoinable
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
48
|
+
# Group.count_joins(:as => :parent, :conditions)
|
49
|
+
def count_joins(options = {})
|
50
|
+
relationship = options.delete(:as) || :parent
|
51
|
+
conditions = options[:conditions] || {}
|
52
|
+
conditions["#{relationship.to_s}_type".to_sym] = ([self.name] + (self.send(:subclasses) - self.included_modules).map(&:name)).flatten.uniq
|
53
|
+
group = options[:group] || "#{relationship}_id"
|
54
|
+
ActsAsJoinable::Relationship.count(:conditions => conditions, :group => group)
|
55
|
+
end
|
56
|
+
|
47
57
|
def acts_as_joinable
|
48
58
|
acts_as_joinable_on
|
49
59
|
end
|
@@ -79,6 +79,7 @@ module ActiveRecord
|
|
79
79
|
|
80
80
|
# Construct attributes for associate pointing to owner.
|
81
81
|
def construct_owner_attributes(reflection)
|
82
|
+
puts "construct_owner_attributes #{@owner.class.name}"
|
82
83
|
if as = reflection.options[:as]
|
83
84
|
{ "#{as}_id" => @owner.id,
|
84
85
|
"#{as}_type" => @owner.class.name.to_s }
|
@@ -101,11 +102,12 @@ module ActiveRecord
|
|
101
102
|
|
102
103
|
# Associate attributes pointing to owner, quoted.
|
103
104
|
def construct_quoted_owner_attributes(reflection)
|
105
|
+
|
104
106
|
if as = reflection.options[:as]
|
105
|
-
|
106
|
-
"#{as}_type"
|
107
|
-
|
108
|
-
|
107
|
+
types = [@owner.class.name.to_s, @owner.class.base_class.name.to_s].map do |clazz|
|
108
|
+
reflection.klass.quote_value(clazz, reflection.klass.columns_hash["#{as}_type"])
|
109
|
+
end
|
110
|
+
{ "#{as}_id" => owner_quoted_id, "#{as}_type" => types }
|
109
111
|
elsif reflection.macro == :belongs_to
|
110
112
|
{ reflection.klass.primary_key => @owner[reflection.primary_key_name] }
|
111
113
|
else
|
@@ -119,6 +121,7 @@ module ActiveRecord
|
|
119
121
|
reflection_primary_key = @reflection.klass.primary_key
|
120
122
|
source_primary_key = @reflection.source_reflection.primary_key_name
|
121
123
|
if @reflection.options[:source_type]
|
124
|
+
puts "@reflection.options[:source_type]"
|
122
125
|
polymorphic_join = construct_polymorphic_sql(
|
123
126
|
@reflection.through_reflection.quoted_table_name,
|
124
127
|
"#{@reflection.source_reflection.options[:foreign_type]}",
|
@@ -139,26 +142,30 @@ module ActiveRecord
|
|
139
142
|
end
|
140
143
|
end
|
141
144
|
|
142
|
-
"INNER JOIN %s ON %s.%s = %s.%s %s #{@reflection.options[:joins]} #{custom_joins}" % [
|
145
|
+
result = "INNER JOIN %s ON %s.%s = %s.%s %s #{@reflection.options[:joins]} #{custom_joins}" % [
|
143
146
|
@reflection.through_reflection.quoted_table_name,
|
144
147
|
@reflection.quoted_table_name, reflection_primary_key,
|
145
148
|
@reflection.through_reflection.quoted_table_name, source_primary_key,
|
146
149
|
polymorphic_join
|
147
150
|
]
|
151
|
+
|
152
|
+
puts "RESULT #{result}"
|
153
|
+
|
154
|
+
result
|
148
155
|
end
|
149
156
|
end
|
150
157
|
|
151
158
|
class HasManyAssociation < AssociationCollection
|
152
159
|
protected
|
153
160
|
def construct_polymorphic_sql(table_name, attribute, clazz = @owner.class)
|
154
|
-
condition = []
|
155
161
|
clazz = clazz.to_s.constantize unless clazz.is_a?(Class)
|
156
162
|
ancestor_classes = (clazz.ancestors.reverse - clazz.included_modules).uniq + clazz.send(:subclasses)
|
163
|
+
in_tree = []
|
157
164
|
while ancestor = ancestor_classes.pop
|
158
165
|
break if ancestor == clazz.base_class.superclass
|
159
|
-
|
166
|
+
in_tree << clazz.quote_value(ancestor.name)
|
160
167
|
end
|
161
|
-
|
168
|
+
"#{table_name}.#{attribute} IN (#{in_tree.join(',')})"
|
162
169
|
end
|
163
170
|
|
164
171
|
# added support for STI with polymorphism
|
@@ -174,10 +181,11 @@ module ActiveRecord
|
|
174
181
|
@finder_sql << " AND (#{polymorphic_conditions})"
|
175
182
|
@finder_sql << " AND (#{conditions})" if conditions
|
176
183
|
else
|
184
|
+
puts "PRIMARY #{@reflection.quoted_table_name}.#{@reflection.primary_key_name}"
|
177
185
|
@finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}"
|
178
186
|
@finder_sql << " AND (#{conditions})" if conditions
|
179
187
|
end
|
180
|
-
|
188
|
+
|
181
189
|
if @reflection.options[:counter_sql]
|
182
190
|
@counter_sql = interpolate_sql(@reflection.options[:counter_sql])
|
183
191
|
elsif @reflection.options[:finder_sql]
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts-as-joinable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 4
|
10
|
+
version: 0.1.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Lance Pollard
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-09-
|
18
|
+
date: 2010-09-22 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|