composite_primary_keys 3.1.11 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -8
- data/lib/composite_primary_keys.rb +53 -36
- data/lib/composite_primary_keys/associations/association.rb +23 -0
- data/lib/composite_primary_keys/associations/association_scope.rb +67 -0
- data/lib/composite_primary_keys/associations/has_and_belongs_to_many_association.rb +31 -121
- data/lib/composite_primary_keys/associations/has_many_association.rb +27 -66
- data/lib/composite_primary_keys/associations/join_dependency/join_association.rb +22 -0
- data/lib/composite_primary_keys/associations/join_dependency/join_part.rb +39 -0
- data/lib/composite_primary_keys/associations/preloader/association.rb +61 -0
- data/lib/composite_primary_keys/associations/preloader/belongs_to.rb +13 -0
- data/lib/composite_primary_keys/associations/preloader/has_and_belongs_to_many.rb +46 -0
- data/lib/composite_primary_keys/attribute_methods/dirty.rb +30 -0
- data/lib/composite_primary_keys/attribute_methods/read.rb +88 -0
- data/lib/composite_primary_keys/attribute_methods/write.rb +33 -0
- data/lib/composite_primary_keys/base.rb +18 -70
- data/lib/composite_primary_keys/composite_predicates.rb +53 -0
- data/lib/composite_primary_keys/connection_adapters/abstract_adapter.rb +6 -4
- data/lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb +19 -41
- data/lib/composite_primary_keys/fixtures.rb +19 -6
- data/lib/composite_primary_keys/persistence.rb +32 -13
- data/lib/composite_primary_keys/relation.rb +23 -16
- data/lib/composite_primary_keys/relation/calculations.rb +48 -0
- data/lib/composite_primary_keys/relation/finder_methods.rb +117 -0
- data/lib/composite_primary_keys/relation/query_methods.rb +24 -0
- data/lib/composite_primary_keys/validations/uniqueness.rb +19 -23
- data/lib/composite_primary_keys/version.rb +5 -5
- data/test/connections/native_mysql/connection.rb +1 -1
- data/test/fixtures/articles.yml +1 -0
- data/test/fixtures/products.yml +2 -4
- data/test/fixtures/readings.yml +1 -0
- data/test/fixtures/suburbs.yml +1 -4
- data/test/fixtures/users.yml +1 -0
- data/test/test_associations.rb +61 -63
- data/test/test_attributes.rb +16 -21
- data/test/test_create.rb +3 -3
- data/test/test_delete.rb +87 -84
- data/test/{test_clone.rb → test_dup.rb} +8 -5
- data/test/test_exists.rb +22 -10
- data/test/test_habtm.rb +0 -74
- data/test/test_ids.rb +2 -1
- data/test/test_miscellaneous.rb +2 -2
- data/test/test_polymorphic.rb +1 -1
- data/test/test_suite.rb +1 -1
- data/test/test_update.rb +3 -3
- metadata +76 -75
- data/lib/composite_primary_keys/association_preload.rb +0 -158
- data/lib/composite_primary_keys/associations.rb +0 -155
- data/lib/composite_primary_keys/associations/association_proxy.rb +0 -33
- data/lib/composite_primary_keys/associations/has_one_association.rb +0 -27
- data/lib/composite_primary_keys/associations/through_association_scope.rb +0 -103
- data/lib/composite_primary_keys/attribute_methods.rb +0 -84
- data/lib/composite_primary_keys/calculations.rb +0 -31
- data/lib/composite_primary_keys/connection_adapters/ibm_db_adapter.rb +0 -21
- data/lib/composite_primary_keys/connection_adapters/oracle_adapter.rb +0 -15
- data/lib/composite_primary_keys/connection_adapters/oracle_enhanced_adapter.rb +0 -17
- data/lib/composite_primary_keys/connection_adapters/sqlite3_adapter.rb +0 -15
- data/lib/composite_primary_keys/finder_methods.rb +0 -123
- data/lib/composite_primary_keys/primary_key.rb +0 -19
- data/lib/composite_primary_keys/query_methods.rb +0 -24
- data/lib/composite_primary_keys/read.rb +0 -25
- data/lib/composite_primary_keys/reflection.rb +0 -37
- data/lib/composite_primary_keys/write.rb +0 -18
data/History.txt
CHANGED
@@ -1,11 +1,6 @@
|
|
1
|
-
==
|
2
|
-
|
3
|
-
|
4
|
-
== 3.1.10 2011-07-08
|
5
|
-
* Bugfix for belongs_to with includes (John Ash)
|
6
|
-
* Improved tests for calling clear on a habtm association, which involved (David Rueck)
|
7
|
-
* Fixed bug that resulted in unrelated records being deleted when calling (David Rueck)
|
8
|
-
* Output deprecation warnings about extra columns in join table CPK-aware (David Rueck)
|
1
|
+
== 4.0.0.beta1 2011-06-09
|
2
|
+
* ActiveRecord 3.1 compatibility. This required a significant rewrite due to
|
3
|
+
all the changes in AR 3.1 versus 3.0.
|
9
4
|
|
10
5
|
== 3.1.9 2011-06-04
|
11
6
|
* Improve HABTM association tests (David Rueck)
|
@@ -19,6 +14,7 @@ Fix AssociationReflection#derive_primary_key for belongs_to relationships (Heinr
|
|
19
14
|
* Minor test cleanup (Charlie Savage)
|
20
15
|
* Make version requirements more explicit (Charlie Savage)
|
21
16
|
* Remove Arel extensions used for calculations (Charlie Savage)
|
17
|
+
* Fix test that included wrong error constant
|
22
18
|
|
23
19
|
== 3.1.6 2011-04-03
|
24
20
|
* Updated belongs_to association to be a bit more flexible with non-CPK (Charlie Savage)
|
@@ -27,12 +23,14 @@ Fix AssociationReflection#derive_primary_key for belongs_to relationships (Heinr
|
|
27
23
|
* Fix write issue when one of they keys in a composite key is
|
28
24
|
called id (Tom Hughes)
|
29
25
|
|
26
|
+
|
30
27
|
== 3.1.5 2011-03-24
|
31
28
|
* Fix simple calculation methods (Charlie Savage)
|
32
29
|
* Fix instantiation of cpk records via associations (Charlie Savage)
|
33
30
|
* Fix Relation#delete (Charlie Savage)
|
34
31
|
* Fix Relation#destroy (Charlie Savage)
|
35
32
|
|
33
|
+
|
36
34
|
== 3.1.4 2011-03-06
|
37
35
|
* Support ActiveRecord 3.0.5 - interpolate_sql was removed and
|
38
36
|
replaced by interpolate_and_sanitize_sql (Charlie Savage)
|
@@ -26,50 +26,67 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
26
26
|
|
27
27
|
unless defined?(ActiveRecord)
|
28
28
|
require 'rubygems'
|
29
|
-
gem 'activerecord', '
|
29
|
+
gem 'activerecord', '=3.1.0.rc1'
|
30
30
|
require 'active_record'
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
require 'active_record/
|
35
|
-
require 'active_record/
|
36
|
-
require 'active_record/
|
37
|
-
|
38
|
-
require 'active_record/associations/
|
33
|
+
# AR files we override
|
34
|
+
require 'active_record/fixtures'
|
35
|
+
require 'active_record/persistence'
|
36
|
+
require 'active_record/relation'
|
37
|
+
|
38
|
+
require 'active_record/associations/association'
|
39
|
+
require 'active_record/associations/association_scope'
|
39
40
|
require 'active_record/associations/has_and_belongs_to_many_association'
|
40
41
|
require 'active_record/associations/has_many_association'
|
41
|
-
require 'active_record/associations/
|
42
|
-
require 'active_record/associations/
|
43
|
-
require 'active_record/associations/
|
44
|
-
require 'active_record/
|
42
|
+
require 'active_record/associations/join_dependency/join_part'
|
43
|
+
require 'active_record/associations/join_dependency/join_association'
|
44
|
+
require 'active_record/associations/preloader/association'
|
45
|
+
require 'active_record/associations/preloader/belongs_to'
|
46
|
+
require 'active_record/associations/preloader/has_and_belongs_to_many'
|
47
|
+
|
48
|
+
require 'active_record/attribute_methods/dirty'
|
49
|
+
require 'active_record/attribute_methods/read'
|
50
|
+
require 'active_record/attribute_methods/write'
|
51
|
+
|
52
|
+
require 'active_record/connection_adapters/abstract_adapter'
|
53
|
+
require 'active_record/connection_adapters/postgresql_adapter'
|
54
|
+
|
55
|
+
require 'active_record/relation/calculations'
|
56
|
+
require 'active_record/relation/finder_methods'
|
45
57
|
require 'active_record/relation/query_methods'
|
46
|
-
require 'active_record/attribute_methods/primary_key'
|
47
|
-
require 'active_record/fixtures'
|
48
58
|
|
59
|
+
require 'active_record/validations/uniqueness'
|
60
|
+
|
61
|
+
|
62
|
+
# CPK files
|
63
|
+
require 'composite_primary_keys/base'
|
49
64
|
require 'composite_primary_keys/composite_arrays'
|
50
|
-
require 'composite_primary_keys/
|
51
|
-
require 'composite_primary_keys/
|
52
|
-
require 'composite_primary_keys/associations/has_one_association'
|
53
|
-
require 'composite_primary_keys/associations/has_many_association'
|
54
|
-
require 'composite_primary_keys/associations/has_and_belongs_to_many_association'
|
55
|
-
require 'composite_primary_keys/associations/through_association_scope'
|
56
|
-
require 'composite_primary_keys/association_preload'
|
65
|
+
require 'composite_primary_keys/composite_predicates'
|
66
|
+
require 'composite_primary_keys/fixtures'
|
57
67
|
require 'composite_primary_keys/persistence'
|
58
|
-
require 'composite_primary_keys/reflection'
|
59
68
|
require 'composite_primary_keys/relation'
|
60
|
-
require 'composite_primary_keys/
|
61
|
-
require 'composite_primary_keys/write'
|
62
|
-
require 'composite_primary_keys/finder_methods'
|
63
|
-
require 'composite_primary_keys/base'
|
64
|
-
require 'composite_primary_keys/calculations'
|
65
|
-
require 'composite_primary_keys/validations/uniqueness'
|
66
|
-
require 'composite_primary_keys/query_methods'
|
67
|
-
require 'composite_primary_keys/primary_key'
|
68
|
-
require 'composite_primary_keys/fixtures'
|
69
|
+
require 'composite_primary_keys/version'
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
require 'composite_primary_keys/associations/association'
|
72
|
+
require 'composite_primary_keys/associations/association_scope'
|
73
|
+
require 'composite_primary_keys/associations/has_and_belongs_to_many_association'
|
74
|
+
require 'composite_primary_keys/associations/has_many_association'
|
75
|
+
require 'composite_primary_keys/associations/join_dependency/join_part'
|
76
|
+
require 'composite_primary_keys/associations/join_dependency/join_association'
|
77
|
+
require 'composite_primary_keys/associations/preloader/association'
|
78
|
+
require 'composite_primary_keys/associations/preloader/belongs_to'
|
79
|
+
require 'composite_primary_keys/associations/preloader/has_and_belongs_to_many'
|
80
|
+
|
81
|
+
require 'composite_primary_keys/attribute_methods/dirty'
|
82
|
+
require 'composite_primary_keys/attribute_methods/read'
|
83
|
+
require 'composite_primary_keys/attribute_methods/write'
|
84
|
+
|
85
|
+
require 'composite_primary_keys/connection_adapters/abstract_adapter'
|
86
|
+
require 'composite_primary_keys/connection_adapters/postgresql_adapter'
|
87
|
+
|
88
|
+
require 'composite_primary_keys/relation/calculations'
|
89
|
+
require 'composite_primary_keys/relation/finder_methods'
|
90
|
+
require 'composite_primary_keys/relation/query_methods'
|
91
|
+
|
92
|
+
require 'composite_primary_keys/validations/uniqueness'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class Association
|
4
|
+
def creation_attributes
|
5
|
+
attributes = {}
|
6
|
+
|
7
|
+
if reflection.macro.in?([:has_one, :has_many]) && !options[:through]
|
8
|
+
# CPK
|
9
|
+
# attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
|
10
|
+
Array(reflection.foreign_key).zip(Array(reflection.active_record_primary_key)).each do |key1, key2|
|
11
|
+
attributes[key1] = owner[key2]
|
12
|
+
end
|
13
|
+
|
14
|
+
if reflection.options[:as]
|
15
|
+
attributes[reflection.type] = owner.class.base_class.name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
attributes
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class AssociationScope
|
4
|
+
def add_constraints(scope)
|
5
|
+
tables = construct_tables
|
6
|
+
|
7
|
+
chain.each_with_index do |reflection, i|
|
8
|
+
table, foreign_table = tables.shift, tables.first
|
9
|
+
|
10
|
+
if reflection.source_macro == :has_and_belongs_to_many
|
11
|
+
join_table = tables.shift
|
12
|
+
|
13
|
+
# CPK
|
14
|
+
# scope = scope.joins(join(
|
15
|
+
# join_table,
|
16
|
+
# table[reflection.active_record_primary_key].
|
17
|
+
# eq(join_table[reflection.association_foreign_key])
|
18
|
+
#))
|
19
|
+
predicate = cpk_join_predicate(table, reflection.association_primary_key,
|
20
|
+
join_table, reflection.association_foreign_key)
|
21
|
+
scope = scope.joins(join(join_table, predicate))
|
22
|
+
|
23
|
+
table, foreign_table = join_table, tables.first
|
24
|
+
end
|
25
|
+
|
26
|
+
if reflection.source_macro == :belongs_to
|
27
|
+
key = reflection.association_primary_key
|
28
|
+
foreign_key = reflection.foreign_key
|
29
|
+
else
|
30
|
+
key = reflection.foreign_key
|
31
|
+
foreign_key = reflection.active_record_primary_key
|
32
|
+
end
|
33
|
+
|
34
|
+
if reflection == chain.last
|
35
|
+
# CPK
|
36
|
+
# scope = scope.where(table[key].eq(owner[foreign_key]))
|
37
|
+
predicate = cpk_join_predicate(table, key, owner, foreign_key)
|
38
|
+
scope = scope.where(predicate)
|
39
|
+
|
40
|
+
conditions[i].each do |condition|
|
41
|
+
if options[:through] && condition.is_a?(Hash)
|
42
|
+
condition = { table.name => condition }
|
43
|
+
end
|
44
|
+
|
45
|
+
scope = scope.where(interpolate(condition))
|
46
|
+
end
|
47
|
+
else
|
48
|
+
# CPK
|
49
|
+
# constraint = table[key].eq(foreign_table[foreign_key])
|
50
|
+
constraint = cpk_join_predicate(table, key, foreign_table, foreign_key)
|
51
|
+
scope = scope.where(predicate)
|
52
|
+
|
53
|
+
join = join(foreign_table, constraint)
|
54
|
+
|
55
|
+
scope = scope.joins(join)
|
56
|
+
|
57
|
+
unless conditions[i].empty?
|
58
|
+
scope = scope.where(sanitize(conditions[i], table))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
scope
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -1,143 +1,53 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Associations
|
3
3
|
class HasAndBelongsToManyAssociation
|
4
|
-
def
|
5
|
-
if
|
6
|
-
|
4
|
+
def insert_record(record, validate = true)
|
5
|
+
return if record.new_record? && !record.save(:validate => validate)
|
6
|
+
|
7
|
+
if options[:insert_sql]
|
8
|
+
owner.connection.insert(interpolate(options[:insert_sql], record))
|
7
9
|
else
|
8
10
|
# CPK
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
conditions << "#{@reflection.quoted_table_name}.#{@reflection.klass.primary_key[i]} = #{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.association_foreign_key[i]}"
|
11
|
+
#stmt = join_table.compile_insert(
|
12
|
+
# join_table[reflection.foreign_key] => owner.id,
|
13
|
+
# join_table[reflection.association_foreign_key] => record.id
|
14
|
+
#)
|
15
|
+
join_values = Hash.new
|
16
|
+
Array(reflection.foreign_key).zip(Array(owner.id)) do |name, value|
|
17
|
+
attribute = join_table[name]
|
18
|
+
join_values[attribute] = value
|
18
19
|
end
|
19
|
-
conditions.join(' AND ')
|
20
|
-
else
|
21
|
-
"#{@reflection.quoted_table_name}.#{@reflection.klass.primary_key} = #{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.association_foreign_key}"
|
22
|
-
end
|
23
|
-
#@join_sql = "INNER JOIN #{@owner.connection.quote_table_name @reflection.options[:join_table]} ON #{@reflection.quoted_table_name}.#{@reflection.klass.primary_key} = #{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.association_foreign_key}"
|
24
|
-
@join_sql = "INNER JOIN #{@owner.connection.quote_table_name @reflection.options[:join_table]} ON (#{join_condition})"
|
25
20
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def insert_record(record, force = true, validate = true)
|
30
|
-
unless record.persisted?
|
31
|
-
if force
|
32
|
-
record.save!
|
33
|
-
else
|
34
|
-
return false unless record.save(:validate => validate)
|
21
|
+
Array(reflection.association_foreign_key).zip(Array(record.id)) do |name, value|
|
22
|
+
attribute = join_table[name]
|
23
|
+
join_values[attribute] = value
|
35
24
|
end
|
36
|
-
end
|
37
|
-
|
38
|
-
if @reflection.options[:insert_sql]
|
39
|
-
@owner.connection.insert(interpolate_and_sanitize_sql(@reflection.options[:insert_sql], record))
|
40
|
-
else
|
41
|
-
relation = Arel::Table.new(@reflection.options[:join_table])
|
42
|
-
timestamps = record_timestamp_columns(record)
|
43
|
-
timezone = record.send(:current_time_from_proper_timezone) if timestamps.any?
|
44
25
|
|
45
|
-
|
46
|
-
#attributes = Hash[columns.map do |column|
|
47
|
-
# name = column.name
|
48
|
-
# value = case name.to_s
|
49
|
-
# when @reflection.primary_key_name.to_s
|
50
|
-
# @owner.id
|
51
|
-
# when @reflection.association_foreign_key.to_s
|
52
|
-
# record.id
|
53
|
-
# when *timestamps
|
54
|
-
# timezone
|
55
|
-
# else
|
56
|
-
# @owner.send(:quote_value, record[name], column) if record.has_attribute?(name)
|
57
|
-
# end
|
58
|
-
# [relation[name], value] unless value.nil?
|
59
|
-
#end]
|
60
|
-
|
61
|
-
# CPK
|
62
|
-
owner_foreign_keys = @reflection.cpk_primary_key.map{|key| key.to_s}
|
63
|
-
association_foreign_keys = Array(@reflection.association_foreign_key).map{|key| key.to_s}
|
26
|
+
stmt = join_table.compile_insert(join_values)
|
64
27
|
|
65
|
-
|
66
|
-
name = column.name.to_s
|
67
|
-
value = case
|
68
|
-
when owner_foreign_keys.include?(name)
|
69
|
-
index = owner_foreign_keys.index(name)
|
70
|
-
primary_keys = Array(@owner.class.primary_key)
|
71
|
-
primary_key = primary_keys[index]
|
72
|
-
@owner[primary_key]
|
73
|
-
when association_foreign_keys.include?(name)
|
74
|
-
index = association_foreign_keys.index(name)
|
75
|
-
primary_keys = Array(@reflection.klass.primary_key)
|
76
|
-
primary_key = primary_keys[index]
|
77
|
-
record[primary_key]
|
78
|
-
when timestamps.include?(name)
|
79
|
-
timezone
|
80
|
-
else
|
81
|
-
@owner.send(:quote_value, record[name], column) if record.has_attribute?(name)
|
82
|
-
end
|
83
|
-
[relation[name], value] unless value.nil?
|
84
|
-
end]
|
85
|
-
|
86
|
-
relation.insert(attributes)
|
28
|
+
owner.connection.insert stmt.to_sql
|
87
29
|
end
|
88
30
|
|
89
|
-
|
31
|
+
record
|
90
32
|
end
|
91
33
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
# records.each { |record| @owner.connection.delete(interpolate_and_sanitize_sql(sql, record)) }
|
96
|
-
# else
|
97
|
-
# relation = Arel::Table.new(@reflection.options[:join_table])
|
98
|
-
# relation.where(relation[@reflection.primary_key_name].eq(@owner.id).
|
99
|
-
# and(relation[@reflection.association_foreign_key].in(records.map { |x| x.id }.compact))
|
100
|
-
# ).delete
|
101
|
-
# end
|
102
|
-
#end
|
103
|
-
|
104
|
-
# CPK
|
105
|
-
def delete_records(records)
|
106
|
-
if sql = @reflection.options[:delete_sql]
|
107
|
-
records.each { |record| @owner.connection.delete(interpolate_and_sanitize_sql(sql, record)) }
|
34
|
+
def delete_records(records, method)
|
35
|
+
if sql = options[:delete_sql]
|
36
|
+
records.each { |record| owner.connection.delete(interpolate(sql, record)) }
|
108
37
|
else
|
109
|
-
relation =
|
38
|
+
relation = join_table
|
39
|
+
# CPK
|
40
|
+
# stmt = relation.where(relation[reflection.foreign_key].eq(owner.id).
|
41
|
+
# and(relation[reflection.association_foreign_key].in(records.map { |x| x.id }.compact))
|
42
|
+
#).compile_delete
|
110
43
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
owner_conditions << relation[column.to_sym].eq(@owner.id[i])
|
115
|
-
end
|
116
|
-
owner_conditions_arel = owner_conditions.inject { |conds, cond| conds.and(cond) }
|
117
|
-
else
|
118
|
-
owner_conditions_arel = relation[@reflection.primary_key_name].eq(@owner.id)
|
119
|
-
end
|
44
|
+
predicate1 = cpk_id_predicate(relation, Array(reflection.foreign_key), Array(owner.id))
|
45
|
+
predicate2 = cpk_in_predicate(relation, Array(reflection.association_foreign_key), records.map { |x| x.id })
|
46
|
+
stmt = relation.where(predicate1.and(predicate2)).compile_delete
|
120
47
|
|
121
|
-
|
122
|
-
association_conditions = []
|
123
|
-
records.each do |rec|
|
124
|
-
record_conditions = []
|
125
|
-
@reflection.association_foreign_key.each_with_index do |column,i|
|
126
|
-
record_conditions << relation[column.to_sym].eq(rec.id[i])
|
127
|
-
end
|
128
|
-
association_conditions << record_conditions.inject { |conds, cond| conds.and(cond) }
|
129
|
-
end
|
130
|
-
association_conditions_arel = association_conditions.inject { |conds, cond| conds.or(cond) }
|
131
|
-
else
|
132
|
-
association_conditions_arel = relation[@reflection.association_foreign_key].in(records.map { |x| x.id }.compact)
|
133
|
-
end
|
134
|
-
|
135
|
-
all_conditions_arel = owner_conditions_arel.and(association_conditions_arel)
|
136
|
-
|
137
|
-
relation.where(all_conditions_arel).delete
|
48
|
+
owner.connection.delete stmt.to_sql
|
138
49
|
end
|
139
50
|
end
|
140
|
-
|
141
51
|
end
|
142
52
|
end
|
143
53
|
end
|
@@ -1,79 +1,40 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Associations
|
3
3
|
class HasManyAssociation
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
when @reflection.options[:as]
|
10
|
-
@finder_sql =
|
11
|
-
"#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " +
|
12
|
-
"#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"
|
13
|
-
@finder_sql << " AND (#{conditions})" if conditions
|
14
|
-
|
15
|
-
else
|
16
|
-
# CPK
|
17
|
-
# @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}"
|
18
|
-
@finder_sql = full_columns_equals(@reflection.table_name, @reflection.cpk_primary_key, owner_quoted_id)
|
19
|
-
@finder_sql << " AND (#{conditions})" if conditions
|
20
|
-
end
|
21
|
-
|
22
|
-
construct_counter_sql
|
23
|
-
end
|
24
|
-
|
25
|
-
def owner_quoted_id
|
26
|
-
if (keys = @reflection.options[:primary_key])
|
27
|
-
keys.is_a?(Array) ? keys.collect {|k| quote_value(@owner.send(k)) } : quote_value(@owner.send(keys))
|
4
|
+
def delete_records(records, method)
|
5
|
+
if method == :destroy
|
6
|
+
records.each { |r| r.destroy }
|
7
|
+
update_counter(-records.length) unless inverse_updates_counter_cache?
|
28
8
|
else
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
records.each { |r| r.destroy }
|
37
|
-
when :delete_all
|
38
|
-
@reflection.klass.delete(records.map { |record| record.id })
|
39
|
-
else
|
40
|
-
relation = Arel::Table.new(@reflection.table_name)
|
41
|
-
# CPK
|
42
|
-
#relation.where(relation[@reflection.primary_key_name].eq(@owner.id).
|
43
|
-
# and(relation[@reflection.klass.primary_key].in(records.map { |r| r.id }))
|
44
|
-
#).update(relation[@reflection.primary_key_name] => nil)
|
45
|
-
|
46
|
-
id_predicate = nil
|
47
|
-
owner_key_values = @reflection.cpk_primary_key.zip([@owner.id].flatten)
|
48
|
-
owner_key_values.each do |key, value|
|
49
|
-
eq = relation[key].eq(value)
|
50
|
-
id_predicate = id_predicate ? id_predicate.and(eq) : eq
|
9
|
+
# CPK
|
10
|
+
# keys = records.map { |r| r[reflection.association_primary_key] }
|
11
|
+
# scope = scoped.where(reflection.association_primary_key => keys)
|
12
|
+
table = Arel::Table.new(reflection.table_name)
|
13
|
+
and_conditions = records.map do |record|
|
14
|
+
eq_conditions = Array(reflection.association_primary_key).map do |name|
|
15
|
+
table[name].eq(record[name])
|
51
16
|
end
|
17
|
+
Arel::Nodes::And.new(eq_conditions)
|
18
|
+
end
|
52
19
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
record_predicate = nil
|
59
|
-
keys.zip(values).each do |key, value|
|
60
|
-
eq = relation[key].eq(value)
|
61
|
-
record_predicate = record_predicate ? record_predicate.and(eq) : eq
|
62
|
-
end
|
63
|
-
record_predicates = record_predicates ? record_predicates.or(record_predicate) : record_predicate
|
64
|
-
end
|
20
|
+
condition = and_conditions.shift
|
21
|
+
and_conditions.each do |and_condition|
|
22
|
+
condition = condition.or(and_condition)
|
23
|
+
end
|
65
24
|
|
66
|
-
|
25
|
+
scope = scoped.where(condition)
|
67
26
|
|
68
|
-
|
69
|
-
|
70
|
-
|
27
|
+
if method == :delete_all
|
28
|
+
update_counter(-scope.delete_all)
|
29
|
+
else
|
30
|
+
# CPK
|
31
|
+
# update_counter(-scope.update_all(reflection.foreign_key => nil))
|
32
|
+
updates = Array(reflection.foreign_key).inject(Hash.new) do |hash, name|
|
33
|
+
hash[name] = nil
|
71
34
|
hash
|
72
35
|
end
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
@owner.class.update_counters(@owner.id, cached_counter_attribute_name => -records.size) if has_cached_counter?
|
36
|
+
update_counter(-scope.update_all(updates))
|
37
|
+
end
|
77
38
|
end
|
78
39
|
end
|
79
40
|
end
|