composite_primary_keys 3.1.11 → 4.0.0.beta1

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.
Files changed (62) hide show
  1. data/History.txt +6 -8
  2. data/lib/composite_primary_keys.rb +53 -36
  3. data/lib/composite_primary_keys/associations/association.rb +23 -0
  4. data/lib/composite_primary_keys/associations/association_scope.rb +67 -0
  5. data/lib/composite_primary_keys/associations/has_and_belongs_to_many_association.rb +31 -121
  6. data/lib/composite_primary_keys/associations/has_many_association.rb +27 -66
  7. data/lib/composite_primary_keys/associations/join_dependency/join_association.rb +22 -0
  8. data/lib/composite_primary_keys/associations/join_dependency/join_part.rb +39 -0
  9. data/lib/composite_primary_keys/associations/preloader/association.rb +61 -0
  10. data/lib/composite_primary_keys/associations/preloader/belongs_to.rb +13 -0
  11. data/lib/composite_primary_keys/associations/preloader/has_and_belongs_to_many.rb +46 -0
  12. data/lib/composite_primary_keys/attribute_methods/dirty.rb +30 -0
  13. data/lib/composite_primary_keys/attribute_methods/read.rb +88 -0
  14. data/lib/composite_primary_keys/attribute_methods/write.rb +33 -0
  15. data/lib/composite_primary_keys/base.rb +18 -70
  16. data/lib/composite_primary_keys/composite_predicates.rb +53 -0
  17. data/lib/composite_primary_keys/connection_adapters/abstract_adapter.rb +6 -4
  18. data/lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb +19 -41
  19. data/lib/composite_primary_keys/fixtures.rb +19 -6
  20. data/lib/composite_primary_keys/persistence.rb +32 -13
  21. data/lib/composite_primary_keys/relation.rb +23 -16
  22. data/lib/composite_primary_keys/relation/calculations.rb +48 -0
  23. data/lib/composite_primary_keys/relation/finder_methods.rb +117 -0
  24. data/lib/composite_primary_keys/relation/query_methods.rb +24 -0
  25. data/lib/composite_primary_keys/validations/uniqueness.rb +19 -23
  26. data/lib/composite_primary_keys/version.rb +5 -5
  27. data/test/connections/native_mysql/connection.rb +1 -1
  28. data/test/fixtures/articles.yml +1 -0
  29. data/test/fixtures/products.yml +2 -4
  30. data/test/fixtures/readings.yml +1 -0
  31. data/test/fixtures/suburbs.yml +1 -4
  32. data/test/fixtures/users.yml +1 -0
  33. data/test/test_associations.rb +61 -63
  34. data/test/test_attributes.rb +16 -21
  35. data/test/test_create.rb +3 -3
  36. data/test/test_delete.rb +87 -84
  37. data/test/{test_clone.rb → test_dup.rb} +8 -5
  38. data/test/test_exists.rb +22 -10
  39. data/test/test_habtm.rb +0 -74
  40. data/test/test_ids.rb +2 -1
  41. data/test/test_miscellaneous.rb +2 -2
  42. data/test/test_polymorphic.rb +1 -1
  43. data/test/test_suite.rb +1 -1
  44. data/test/test_update.rb +3 -3
  45. metadata +76 -75
  46. data/lib/composite_primary_keys/association_preload.rb +0 -158
  47. data/lib/composite_primary_keys/associations.rb +0 -155
  48. data/lib/composite_primary_keys/associations/association_proxy.rb +0 -33
  49. data/lib/composite_primary_keys/associations/has_one_association.rb +0 -27
  50. data/lib/composite_primary_keys/associations/through_association_scope.rb +0 -103
  51. data/lib/composite_primary_keys/attribute_methods.rb +0 -84
  52. data/lib/composite_primary_keys/calculations.rb +0 -31
  53. data/lib/composite_primary_keys/connection_adapters/ibm_db_adapter.rb +0 -21
  54. data/lib/composite_primary_keys/connection_adapters/oracle_adapter.rb +0 -15
  55. data/lib/composite_primary_keys/connection_adapters/oracle_enhanced_adapter.rb +0 -17
  56. data/lib/composite_primary_keys/connection_adapters/sqlite3_adapter.rb +0 -15
  57. data/lib/composite_primary_keys/finder_methods.rb +0 -123
  58. data/lib/composite_primary_keys/primary_key.rb +0 -19
  59. data/lib/composite_primary_keys/query_methods.rb +0 -24
  60. data/lib/composite_primary_keys/read.rb +0 -25
  61. data/lib/composite_primary_keys/reflection.rb +0 -37
  62. data/lib/composite_primary_keys/write.rb +0 -18
@@ -1,158 +0,0 @@
1
- module CompositePrimaryKeys
2
- module ActiveRecord
3
- module AssociationPreload
4
- def self.append_features(base)
5
- super
6
- base.send(:extend, ClassMethods)
7
- end
8
-
9
- # Composite key versions of Association functions
10
- module ClassMethods
11
- def preload_has_and_belongs_to_many_association(records, reflection, preload_options={})
12
- table_name = reflection.klass.quoted_table_name
13
- id_to_record_map, ids = construct_id_map(records)
14
- records.each {|record| record.send(reflection.name).loaded}
15
- options = reflection.options
16
-
17
- if composite?
18
- where = (primary_key * ids.size).in_groups_of(primary_key.size).map do |keys|
19
- "(" + keys.map{|key| "t0.#{connection.quote_column_name(key)} = ?"}.join(" AND ") + ")"
20
- end.join(" OR ")
21
-
22
- conditions = [where, ids].flatten
23
- joins = "INNER JOIN #{connection.quote_table_name options[:join_table]} t0 ON #{full_composite_join_clause(reflection, reflection.klass.table_name, reflection.klass.primary_key, 't0', reflection.association_foreign_key)}"
24
- parent_primary_keys = reflection.cpk_primary_key.map{|k| "t0.#{connection.quote_column_name(k)}"}
25
- concat_arr = parent_primary_keys.zip(["'#{CompositePrimaryKeys::ID_SEP}'"] * (parent_primary_keys.size - 1)).flatten.compact
26
- parent_record_id = connection.concat(*concat_arr)
27
- else
28
- conditions = "t0.#{reflection.primary_key_name} #{in_or_equals_for_ids(ids)}"
29
- conditions << append_conditions(reflection, preload_options)
30
- conditions = [conditions, ids]
31
- joins = "INNER JOIN #{connection.quote_table_name options[:join_table]} t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}"
32
- parent_record_id = reflection.primary_key_name
33
- end
34
-
35
- associated_records = reflection.klass.unscoped.where(conditions).
36
- includes(options[:include]).
37
- joins(joins).
38
- select("#{options[:select] || table_name+'.*'}, #{parent_record_id} as the_parent_record_id").
39
- order(options[:order]).to_a
40
-
41
- set_association_collection_records(id_to_record_map, reflection.name, associated_records, 'the_parent_record_id')
42
- end
43
-
44
- def preload_belongs_to_association(records, reflection, preload_options={})
45
- return if records.first.send("loaded_#{reflection.name}?")
46
- options = reflection.options
47
-
48
- ids = Array.new
49
-
50
- if options[:polymorphic]
51
- # CPK
52
- #polymorph_type = options[:foreign_type]
53
- #klasses_and_ids = {}
54
-
55
- # Construct a mapping from klass to a list of ids to load and a mapping of those ids back to their parent_records
56
- #records.each do |record|
57
- # if klass = record.send(polymorph_type)
58
- # klass_id = record.send(primary_key_name)
59
- # if klass_id
60
- # id_map = klasses_and_ids[klass] ||= {}
61
- # id_list_for_klass_id = (id_map[klass_id.to_s] ||= [])
62
- # id_list_for_klass_id << record
63
- # end
64
- # end
65
- #end
66
- #klasses_and_ids = klasses_and_ids.to_a
67
- raise AssociationNotSupported, "Polymorphic joins not supported for composite keys"
68
- else
69
- # I need to keep the original ids for each record (as opposed to the stringified) so
70
- # that they get properly converted for each db so the id_map ends up looking like:
71
- #
72
- # { '1,2' => {:id => [1,2], :records => [...records...]}}
73
- id_map = {}
74
-
75
- records.each do |record|
76
- keys = record[reflection.cpk_primary_key]
77
- ids << keys
78
-
79
- mapped_records = (id_map[keys.to_s] ||= [])
80
- mapped_records << record
81
- end
82
-
83
- klasses_and_ids = [[reflection.klass.name, id_map]]
84
- end
85
-
86
- klasses_and_ids.each do |klass_and_id|
87
- klass_name, id_map = *klass_and_id
88
- next if id_map.empty?
89
- klass = klass_name.constantize
90
-
91
- table_name = klass.quoted_table_name
92
- primary_key = [reflection.options[:primary_key] || klass.primary_key].flatten
93
-
94
- # CPK
95
- conditions = id_map.map do |key, value|
96
- "(" +
97
- primary_key.map do |key|
98
- "#{table_name}.#{connection.quote_column_name(key)} = ?"
99
- end.join(' AND ') + ")"
100
- end.join(' OR ')
101
-
102
- conditions << append_conditions(reflection, preload_options)
103
-
104
- conditions = [conditions] + ids.uniq.flatten
105
-
106
- associated_records = klass.unscoped.where(conditions).apply_finder_options(options.slice(:include, :select, :joins, :order)).to_a
107
-
108
- set_association_single_records(id_map, reflection.name, associated_records, primary_key)
109
- end
110
- end
111
-
112
- def find_associated_records(ids, reflection, preload_options)
113
- options = reflection.options
114
- table_name = reflection.klass.quoted_table_name
115
-
116
- if interface = reflection.options[:as]
117
- conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} #{in_or_equals_for_ids(ids)} and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{self.base_class.sti_name}'"
118
- else
119
- foreign_key = reflection.cpk_primary_key
120
-
121
- where = (foreign_key * ids.size).in_groups_of(foreign_key.size).map do |keys|
122
- "(" + keys.map{|key| "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name(key)} = ?"}.join(" AND ") + ")"
123
- end.join(" OR ")
124
-
125
- conditions = [where, ids].flatten
126
- end
127
-
128
- conditions[0] << append_conditions(reflection, preload_options)
129
-
130
- find_options = {
131
- :select => preload_options[:select] || options[:select] || "#{table_name}.*",
132
- :include => preload_options[:include] || options[:include],
133
- # CPK
134
- # :conditions => [conditions, ids],
135
- :conditions => conditions,
136
- :joins => options[:joins],
137
- :group => preload_options[:group] || options[:group],
138
- :order => preload_options[:order] || options[:order]
139
- }
140
-
141
- reflection.klass.unscoped.apply_finder_options(find_options).to_a
142
- end
143
-
144
- def full_composite_join_clause(reflection, table1, full_keys1, table2, full_keys2)
145
- connection = reflection.active_record.connection
146
- full_keys1 = full_keys1.split(CompositePrimaryKeys::ID_SEP) if full_keys1.is_a?(String)
147
- full_keys2 = full_keys2.split(CompositePrimaryKeys::ID_SEP) if full_keys2.is_a?(String)
148
- where_clause = [full_keys1, full_keys2].transpose.map do |key_pair|
149
- quoted1 = connection.quote_table_name(table1)
150
- quoted2 = connection.quote_table_name(table2)
151
- "#{quoted1}.#{connection.quote_column_name(key_pair.first)}=#{quoted2}.#{connection.quote_column_name(key_pair.last)}"
152
- end.join(" AND ")
153
- "(#{where_clause})"
154
- end
155
- end
156
- end
157
- end
158
- end
@@ -1,155 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- module ClassMethods
4
- class JoinDependency
5
- class JoinBase
6
- def aliased_primary_key
7
- # CPK
8
- # "#{aliased_prefix}_r0"
9
-
10
- active_record.composite? ?
11
- primary_key.inject([]) {|aliased_keys, key| aliased_keys << "#{ aliased_prefix }_r#{aliased_keys.length}"} :
12
- "#{ aliased_prefix }_r0"
13
- end
14
-
15
- def record_id(row)
16
- # CPK
17
- # row[aliased_primary_key]
18
- active_record.composite? ?
19
- aliased_primary_key.map {|key| row[key]}.to_composite_keys :
20
- row[aliased_primary_key]
21
- end
22
-
23
- def column_names_with_alias
24
- unless defined?(@column_names_with_alias)
25
- @column_names_with_alias = []
26
- keys = active_record.composite? ? primary_key.map(&:to_s) : [primary_key]
27
- (keys + (column_names - keys)).each_with_index do |column_name, i|
28
- @column_names_with_alias << [column_name, "#{ aliased_prefix }_r#{ i }"]
29
- end
30
- end
31
- @column_names_with_alias
32
- end
33
- end
34
-
35
- class JoinAssociation
36
- # Ugly to include this twice, but I couldn't figure out how to make this
37
- # work via a module
38
- def composite_join_predicates(table1, keys1, table2, keys2)
39
- attributes1 = [keys1].flatten.map do |key|
40
- table1[key]
41
- end
42
-
43
- attributes2 = [keys2].flatten.map do |key|
44
- table2[key]
45
- end
46
-
47
- [attributes1, attributes2].transpose.map do |attribute1, attribute2|
48
- attribute1.eq(attribute2)
49
- end
50
- end
51
-
52
- def association_join
53
- return @join if @join
54
-
55
- aliased_table = Arel::Table.new(table_name, :as => @aliased_table_name,
56
- :engine => arel_engine,
57
- :columns => klass.columns)
58
-
59
- parent_table = Arel::Table.new(parent.table_name, :as => parent.aliased_table_name,
60
- :engine => arel_engine,
61
- :columns => parent.active_record.columns)
62
-
63
- @join = case reflection.macro
64
- when :has_and_belongs_to_many
65
- join_table = Arel::Table.new(options[:join_table], :as => aliased_join_table_name, :engine => arel_engine)
66
- fk = options[:foreign_key] || reflection.active_record.to_s.foreign_key
67
- klass_fk = options[:association_foreign_key] || klass.to_s.foreign_key
68
-
69
- [
70
- join_table[fk].eq(parent_table[reflection.active_record.primary_key]),
71
- aliased_table[klass.primary_key].eq(join_table[klass_fk])
72
- ]
73
- when :has_many, :has_one
74
- if reflection.options[:through]
75
- join_table = Arel::Table.new(through_reflection.klass.table_name, :as => aliased_join_table_name, :engine => arel_engine)
76
- jt_as_extra = jt_source_extra = jt_sti_extra = nil
77
- first_key = second_key = as_extra = nil
78
-
79
- if through_reflection.macro == :belongs_to
80
- jt_primary_key = through_reflection.primary_key_name
81
- jt_foreign_key = through_reflection.association_primary_key
82
- else
83
- jt_primary_key = through_reflection.active_record_primary_key
84
- jt_foreign_key = through_reflection.primary_key_name
85
-
86
- if through_reflection.options[:as] # has_many :through against a polymorphic join
87
- jt_as_extra = join_table[through_reflection.options[:as].to_s + '_type'].eq(parent.active_record.base_class.name)
88
- end
89
- end
90
-
91
- case source_reflection.macro
92
- when :has_many
93
- if source_reflection.options[:as]
94
- first_key = "#{source_reflection.options[:as]}_id"
95
- second_key = options[:foreign_key] || primary_key
96
- as_extra = aliased_table["#{source_reflection.options[:as]}_type"].eq(source_reflection.active_record.base_class.name)
97
- else
98
- first_key = through_reflection.klass.base_class.to_s.foreign_key
99
- second_key = options[:foreign_key] || primary_key
100
- end
101
-
102
- unless through_reflection.klass.descends_from_active_record?
103
- jt_sti_extra = join_table[through_reflection.active_record.inheritance_column].eq(through_reflection.klass.sti_name)
104
- end
105
- when :belongs_to
106
- first_key = primary_key
107
- if reflection.options[:source_type]
108
- second_key = source_reflection.association_foreign_key
109
- jt_source_extra = join_table[reflection.source_reflection.options[:foreign_type]].eq(reflection.options[:source_type])
110
- else
111
- second_key = source_reflection.primary_key_name
112
- end
113
- end
114
-
115
- [
116
- [parent_table[jt_primary_key].eq(join_table[jt_foreign_key]), jt_as_extra, jt_source_extra, jt_sti_extra].reject{|x| x.blank? },
117
- aliased_table[first_key].eq(join_table[second_key])
118
- ]
119
- elsif reflection.options[:as]
120
- id_rel = aliased_table["#{reflection.options[:as]}_id"].eq(parent_table[parent.primary_key])
121
- type_rel = aliased_table["#{reflection.options[:as]}_type"].eq(parent.active_record.base_class.name)
122
- [id_rel, type_rel]
123
- else
124
- foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
125
- # CPK
126
- #[aliased_table[foreign_key].eq(parent_table[reflection.options[:primary_key] || parent.primary_key])]
127
- composite_join_predicates(aliased_table, foreign_key,
128
- parent_table, reflection.options[:primary_key] || parent.primary_key)
129
- end
130
- when :belongs_to
131
- #[aliased_table[options[:primary_key] || reflection.klass.primary_key].eq(parent_table[options[:foreign_key] || reflection.primary_key_name])]
132
- composite_join_predicates(aliased_table, options[:primary_key] || reflection.klass.primary_key, parent_table, options[:foreign_key] || reflection.primary_key_name)
133
- end
134
-
135
- unless klass.descends_from_active_record?
136
- sti_column = aliased_table[klass.inheritance_column]
137
- sti_condition = sti_column.eq(klass.sti_name)
138
- klass.descendants.each {|subclass| sti_condition = sti_condition.or(sti_column.eq(subclass.sti_name)) }
139
-
140
- @join << sti_condition
141
- end
142
-
143
- [through_reflection, reflection].each do |ref|
144
- if ref && ref.options[:conditions]
145
- @join << process_conditions(ref.options[:conditions], aliased_table_name)
146
- end
147
- end
148
-
149
- @join
150
- end
151
- end
152
- end
153
- end
154
- end
155
- end
@@ -1,33 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class AssociationProxy
4
- def full_columns_equals(table_name, keys, quoted_ids)
5
- quoted_table_name = @owner.connection.quote_table_name(table_name)
6
-
7
- keys = [keys].flatten
8
- ids = [quoted_ids].flatten
9
-
10
- [keys,ids].transpose.map do |key, id|
11
- "(#{quoted_table_name}.#{@owner.connection.quote_column_name(key)} = #{id})"
12
- end.join(' AND ')
13
- end
14
-
15
- def set_belongs_to_association_for(record)
16
- if @reflection.options[:as]
17
- record["#{@reflection.options[:as]}_id"] = @owner.id unless @owner.new_record?
18
- record["#{@reflection.options[:as]}_type"] = @owner.class.base_class.name.to_s
19
- else
20
- unless @owner.new_record?
21
- primary_keys = Array(@reflection.options[:primary_key] || :id)
22
- # CPK
23
- # record[@reflection.primary_key_name] = @owner.send(primary_key)
24
- # Need to flatten because a key may be :id giving a composite key
25
- values = primary_keys.map {|key| @owner.send(key)}.flatten
26
- key_values = @reflection.cpk_primary_key.zip(values)
27
- key_values.each {|key, value| record[key] = value}
28
- end
29
- end
30
- end
31
- end
32
- end
33
- end
@@ -1,27 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class HasOneAssociation
4
- def construct_sql
5
- case
6
- when @reflection.options[:as]
7
- @finder_sql =
8
- "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " +
9
- "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"
10
- else
11
- # CPK
12
- #@finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}"
13
- @finder_sql = full_columns_equals(@reflection.table_name, @reflection.cpk_primary_key, owner_quoted_id)
14
- end
15
- @finder_sql << " AND (#{conditions})" if conditions
16
- end
17
-
18
- def owner_quoted_id
19
- if (keys = @reflection.options[:primary_key])
20
- keys.is_a?(Array) ? keys.collect {|k| @owner.class.quote_value(@owner.send(k)) } : @owner.class.quote_value(@owner.send(keys))
21
- else
22
- @owner.quoted_id
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,103 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- module ThroughAssociationScope
4
- def composite_join_clause(table1, keys1, table2, keys2)
5
- predicates = composite_join_predicates(table1, keys1, table2, keys2)
6
-
7
- join_clause = predicates.map do |predicate|
8
- predicate.to_sql
9
- end.join(" AND ")
10
-
11
- "(#{join_clause})"
12
- end
13
-
14
- def composite_join_predicates(table1, keys1, table2, keys2)
15
- attributes1 = [keys1].flatten.map do |key|
16
- table1[key]
17
- end
18
-
19
- attributes2 = [keys2].flatten.map do |key|
20
- table2[key]
21
- end
22
-
23
- [attributes1, attributes2].transpose.map do |attribute1, attribute2|
24
- attribute1.eq(attribute2)
25
- end
26
- end
27
-
28
- def composite_ids_hash(keys, ids)
29
- [keys].flatten.zip([ids].flatten).inject(Hash.new) do |hash, (key, value)|
30
- hash[key] = value
31
- hash
32
- end
33
- end
34
-
35
- def construct_quoted_owner_attributes(reflection)
36
- if as = reflection.options[:as]
37
- { "#{as}_id" => owner_quoted_id,
38
- "#{as}_type" => reflection.klass.quote_value(
39
- @owner.class.base_class.name.to_s,
40
- reflection.klass.columns_hash["#{as}_type"]) }
41
- elsif reflection.macro == :belongs_to
42
- # CPK
43
- # { reflection.klass.primary_key => @owner[reflection.primary_key_name] }
44
- composite_ids_hash(reflection.klass.primary_key, @owner.quoted_id)
45
- else
46
- # CPK
47
- #{ reflection.primary_key_name => owner_quoted_id }
48
- composite_ids_hash(reflection.cpk_primary_key, @owner.quoted_id)
49
- end
50
- end
51
-
52
- # Construct attributes for associate pointing to owner.
53
- def construct_owner_attributes(reflection)
54
- if as = reflection.options[:as]
55
- { "#{as}_id" => @owner.id,
56
- "#{as}_type" => @owner.class.base_class.name.to_s }
57
- else
58
- # CPK
59
- # { reflection.primary_key_name => @owner.id }
60
- composite_ids_hash(reflection.cpk_primary_key, @owner.id)
61
- end
62
- end
63
-
64
- def construct_joins(custom_joins = nil)
65
- polymorphic_join = nil
66
- if @reflection.source_reflection.macro == :belongs_to
67
- reflection_primary_key = @reflection.klass.primary_key
68
- source_primary_key = @reflection.source_reflection.cpk_primary_key
69
- if @reflection.options[:source_type]
70
- polymorphic_join = "AND %s.%s = %s" % [
71
- @reflection.through_reflection.quoted_table_name, "#{@reflection.source_reflection.options[:foreign_type]}",
72
- @owner.class.quote_value(@reflection.options[:source_type])
73
- ]
74
- end
75
- else
76
- reflection_primary_key = @reflection.source_reflection.cpk_primary_key
77
- source_primary_key = @reflection.through_reflection.klass.primary_key
78
- if @reflection.source_reflection.options[:as]
79
- polymorphic_join = "AND %s.%s = %s" % [
80
- @reflection.quoted_table_name, "#{@reflection.source_reflection.options[:as]}_type",
81
- @owner.class.quote_value(@reflection.through_reflection.klass.name)
82
- ]
83
- end
84
- end
85
-
86
- # CPK
87
- # "INNER JOIN %s ON %s.%s = %s.%s %s #{@reflection.options[:joins]} #{custom_joins}" % [
88
- # @reflection.through_reflection.quoted_table_name,
89
- # @reflection.quoted_table_name, reflection_primary_key,
90
- # @reflection.through_reflection.quoted_table_name, source_primary_key,
91
- # polymorphic_join
92
- # ]
93
-
94
- "INNER JOIN %s ON %s %s #{@reflection.options[:joins]} #{custom_joins}" % [
95
- @reflection.through_reflection.quoted_table_name,
96
- composite_join_clause(@reflection.klass.arel_table, reflection_primary_key,
97
- @reflection.through_reflection.klass.arel_table, source_primary_key),
98
- polymorphic_join
99
- ]
100
- end
101
- end
102
- end
103
- end