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 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.3"
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"
@@ -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
- { "#{as}_id" => owner_quoted_id,
106
- "#{as}_type" => reflection.klass.quote_value(
107
- @owner.class.name.to_s,
108
- reflection.klass.columns_hash["#{as}_type"]) }
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
- condition << "#{table_name}.#{attribute} = #{clazz.quote_value(ancestor.name)}"
166
+ in_tree << clazz.quote_value(ancestor.name)
160
167
  end
161
- condition.join(" OR ")
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: 29
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 3
10
- version: 0.1.3
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-21 00:00:00 -05:00
18
+ date: 2010-09-22 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies: []
21
21