composite_primary_keys 8.1.0 → 8.1.1
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.
- checksums.yaml +4 -4
- data/History.rdoc +642 -625
- data/README.rdoc +5 -2
- data/lib/composite_primary_keys.rb +115 -115
- data/lib/composite_primary_keys/associations/association.rb +23 -23
- data/lib/composite_primary_keys/associations/association_scope.rb +73 -73
- data/lib/composite_primary_keys/associations/collection_association.rb +14 -14
- data/lib/composite_primary_keys/associations/has_many_association.rb +69 -69
- data/lib/composite_primary_keys/associations/join_dependency.rb +87 -87
- data/lib/composite_primary_keys/associations/preloader/association.rb +90 -90
- data/lib/composite_primary_keys/associations/singular_association.rb +18 -18
- data/lib/composite_primary_keys/attribute_methods.rb +9 -9
- data/lib/composite_primary_keys/attribute_methods/dirty.rb +29 -29
- data/lib/composite_primary_keys/attribute_methods/read.rb +24 -24
- data/lib/composite_primary_keys/attribute_methods/write.rb +30 -30
- data/lib/composite_primary_keys/attribute_set/builder.rb +19 -19
- data/lib/composite_primary_keys/base.rb +129 -135
- data/lib/composite_primary_keys/composite_arrays.rb +43 -43
- data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb +2 -3
- data/lib/composite_primary_keys/core.rb +60 -60
- data/lib/composite_primary_keys/persistence.rb +56 -56
- data/lib/composite_primary_keys/relation.rb +68 -68
- data/lib/composite_primary_keys/relation/calculations.rb +78 -78
- data/lib/composite_primary_keys/relation/finder_methods.rb +179 -179
- data/lib/composite_primary_keys/sanitization.rb +52 -52
- data/lib/composite_primary_keys/validations/uniqueness.rb +36 -36
- data/lib/composite_primary_keys/version.rb +8 -8
- data/tasks/databases/sqlserver.rake +27 -27
- data/test/abstract_unit.rb +114 -113
- data/test/connections/databases.example.yml +25 -25
- data/test/connections/native_sqlserver/connection.rb +11 -11
- data/test/fixtures/db_definitions/mysql.sql +218 -218
- data/test/fixtures/db_definitions/postgresql.sql +220 -220
- data/test/fixtures/db_definitions/sqlite.sql +206 -206
- data/test/fixtures/db_definitions/sqlserver.drop.sql +91 -91
- data/test/fixtures/db_definitions/sqlserver.sql +226 -226
- data/test/fixtures/employee.rb +11 -11
- data/test/fixtures/salary.rb +5 -5
- data/test/test_associations.rb +341 -340
- data/test/test_attributes.rb +60 -60
- data/test/test_create.rb +157 -157
- data/test/test_delete.rb +158 -158
- data/test/test_delete_all.rb +33 -28
- data/test/test_enum.rb +21 -21
- data/test/test_equal.rb +26 -26
- data/test/test_find.rb +119 -118
- data/test/test_habtm.rb +117 -113
- data/test/test_polymorphic.rb +27 -26
- data/test/test_tutorial_example.rb +25 -25
- metadata +44 -2
@@ -1,43 +1,43 @@
|
|
1
|
-
module CompositePrimaryKeys
|
2
|
-
ID_SEP = ','
|
3
|
-
ID_SET_SEP = ';'
|
4
|
-
|
5
|
-
module ArrayExtension
|
6
|
-
def to_composite_keys
|
7
|
-
CompositeKeys.new(self)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.normalize(ids)
|
12
|
-
ids.map do |id|
|
13
|
-
if id.is_a?(Array)
|
14
|
-
normalize(id)
|
15
|
-
elsif id.is_a?(String) && id.index(ID_SEP)
|
16
|
-
id.split(ID_SEP)
|
17
|
-
else
|
18
|
-
id
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class CompositeKeys < Array
|
24
|
-
|
25
|
-
def self.parse(value)
|
26
|
-
case value
|
27
|
-
when Array
|
28
|
-
value.to_composite_keys
|
29
|
-
when String
|
30
|
-
self.new(value.split(ID_SEP))
|
31
|
-
else
|
32
|
-
raise(ArgumentError, "Unsupported type: #{value}")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def to_s
|
37
|
-
# Doing this makes it easier to parse Base#[](attr_name)
|
38
|
-
join(ID_SEP)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
Array.send(:include, CompositePrimaryKeys::ArrayExtension)
|
1
|
+
module CompositePrimaryKeys
|
2
|
+
ID_SEP = ','
|
3
|
+
ID_SET_SEP = ';'
|
4
|
+
|
5
|
+
module ArrayExtension
|
6
|
+
def to_composite_keys
|
7
|
+
CompositeKeys.new(self)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.normalize(ids)
|
12
|
+
ids.map do |id|
|
13
|
+
if id.is_a?(Array)
|
14
|
+
normalize(id)
|
15
|
+
elsif id.is_a?(String) && id.index(ID_SEP)
|
16
|
+
id.split(ID_SEP)
|
17
|
+
else
|
18
|
+
id
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class CompositeKeys < Array
|
24
|
+
|
25
|
+
def self.parse(value)
|
26
|
+
case value
|
27
|
+
when Array
|
28
|
+
value.to_composite_keys
|
29
|
+
when String
|
30
|
+
self.new(value.split(ID_SEP))
|
31
|
+
else
|
32
|
+
raise(ArgumentError, "Unsupported type: #{value}")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
# Doing this makes it easier to parse Base#[](attr_name)
|
38
|
+
join(ID_SEP)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Array.send(:include, CompositePrimaryKeys::ArrayExtension)
|
data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb
CHANGED
@@ -9,7 +9,7 @@ module ActiveRecord
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.establish_connection(spec =
|
12
|
+
def self.establish_connection(spec = nil)
|
13
13
|
spec ||= ActiveRecord::ConnectionHandling::DEFAULT_ENV.call.to_sym
|
14
14
|
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new configurations
|
15
15
|
spec = resolver.spec(spec)
|
@@ -64,8 +64,7 @@ module ActiveRecord
|
|
64
64
|
connection_handler.clear_active_connections!
|
65
65
|
end
|
66
66
|
|
67
|
-
delegate :clear_reloadable_connections!,
|
68
|
-
:clear_all_connections!,:verify_active_connections!, :to => :connection_handler
|
67
|
+
delegate :clear_reloadable_connections!, :clear_all_connections!, :to => :connection_handler
|
69
68
|
end
|
70
69
|
end
|
71
70
|
end
|
@@ -1,61 +1,61 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Core
|
3
|
-
def initialize_dup(other) # :nodoc:
|
4
|
-
@attributes = @attributes.dup
|
5
|
-
# CPK
|
6
|
-
# @attributes.reset(self.class.primary_key)
|
7
|
-
Array(self.class.primary_key).each {|key| @attributes.reset(key)}
|
8
|
-
|
9
|
-
run_callbacks(:initialize) unless _initialize_callbacks.empty?
|
10
|
-
|
11
|
-
@aggregation_cache = {}
|
12
|
-
@association_cache = {}
|
13
|
-
|
14
|
-
@new_record = true
|
15
|
-
@destroyed = false
|
16
|
-
|
17
|
-
super
|
18
|
-
end
|
19
|
-
|
20
|
-
module ClassMethods
|
21
|
-
def find(*ids) # :nodoc:
|
22
|
-
# We don't have cache keys for this stuff yet
|
23
|
-
return super unless ids.length == 1
|
24
|
-
# Allow symbols to super to maintain compatibility for deprecated finders until Rails 5
|
25
|
-
return super if ids.first.kind_of?(Symbol)
|
26
|
-
return super if block_given? ||
|
27
|
-
primary_key.nil? ||
|
28
|
-
default_scopes.any? ||
|
29
|
-
current_scope ||
|
30
|
-
columns_hash.include?(inheritance_column) ||
|
31
|
-
ids.first.kind_of?(Array)
|
32
|
-
|
33
|
-
# CPK
|
34
|
-
return super if self.composite?
|
35
|
-
|
36
|
-
id = ids.first
|
37
|
-
if ActiveRecord::Base === id
|
38
|
-
id = id.id
|
39
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
40
|
-
You are passing an instance of ActiveRecord::Base to `find`.
|
41
|
-
Please pass the id of the object by calling `.id`
|
42
|
-
MSG
|
43
|
-
end
|
44
|
-
key = primary_key
|
45
|
-
|
46
|
-
s = find_by_statement_cache[key] || find_by_statement_cache.synchronize {
|
47
|
-
find_by_statement_cache[key] ||= StatementCache.create(connection) { |params|
|
48
|
-
where(key => params.bind).limit(1)
|
49
|
-
}
|
50
|
-
}
|
51
|
-
record = s.execute([id], self, connection).first
|
52
|
-
unless record
|
53
|
-
raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}"
|
54
|
-
end
|
55
|
-
record
|
56
|
-
rescue RangeError
|
57
|
-
raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module Core
|
3
|
+
def initialize_dup(other) # :nodoc:
|
4
|
+
@attributes = @attributes.dup
|
5
|
+
# CPK
|
6
|
+
# @attributes.reset(self.class.primary_key)
|
7
|
+
Array(self.class.primary_key).each {|key| @attributes.reset(key)}
|
8
|
+
|
9
|
+
run_callbacks(:initialize) unless _initialize_callbacks.empty?
|
10
|
+
|
11
|
+
@aggregation_cache = {}
|
12
|
+
@association_cache = {}
|
13
|
+
|
14
|
+
@new_record = true
|
15
|
+
@destroyed = false
|
16
|
+
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
def find(*ids) # :nodoc:
|
22
|
+
# We don't have cache keys for this stuff yet
|
23
|
+
return super unless ids.length == 1
|
24
|
+
# Allow symbols to super to maintain compatibility for deprecated finders until Rails 5
|
25
|
+
return super if ids.first.kind_of?(Symbol)
|
26
|
+
return super if block_given? ||
|
27
|
+
primary_key.nil? ||
|
28
|
+
default_scopes.any? ||
|
29
|
+
current_scope ||
|
30
|
+
columns_hash.include?(inheritance_column) ||
|
31
|
+
ids.first.kind_of?(Array)
|
32
|
+
|
33
|
+
# CPK
|
34
|
+
return super if self.composite?
|
35
|
+
|
36
|
+
id = ids.first
|
37
|
+
if ActiveRecord::Base === id
|
38
|
+
id = id.id
|
39
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
40
|
+
You are passing an instance of ActiveRecord::Base to `find`.
|
41
|
+
Please pass the id of the object by calling `.id`
|
42
|
+
MSG
|
43
|
+
end
|
44
|
+
key = primary_key
|
45
|
+
|
46
|
+
s = find_by_statement_cache[key] || find_by_statement_cache.synchronize {
|
47
|
+
find_by_statement_cache[key] ||= StatementCache.create(connection) { |params|
|
48
|
+
where(key => params.bind).limit(1)
|
49
|
+
}
|
50
|
+
}
|
51
|
+
record = s.execute([id], self, connection).first
|
52
|
+
unless record
|
53
|
+
raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}"
|
54
|
+
end
|
55
|
+
record
|
56
|
+
rescue RangeError
|
57
|
+
raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
61
|
end
|
@@ -1,57 +1,57 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Persistence
|
3
|
-
def relation_for_destroy
|
4
|
-
# CPK
|
5
|
-
if self.composite?
|
6
|
-
relation = self.class.unscoped
|
7
|
-
|
8
|
-
Array(self.class.primary_key).each_with_index do |key, index|
|
9
|
-
column = self.class.columns_hash[key]
|
10
|
-
substitute = self.class.connection.substitute_at(column, index)
|
11
|
-
relation = relation.where(self.class.arel_table[key].eq(substitute))
|
12
|
-
relation.bind_values += [[column, self[key]]]
|
13
|
-
end
|
14
|
-
|
15
|
-
relation
|
16
|
-
else
|
17
|
-
pk = self.class.primary_key
|
18
|
-
column = self.class.columns_hash[pk]
|
19
|
-
substitute = self.class.connection.substitute_at(column, 0)
|
20
|
-
|
21
|
-
relation = self.class.unscoped.where(
|
22
|
-
self.class.arel_table[pk].eq(substitute))
|
23
|
-
|
24
|
-
relation.bind_values = [[column, id]]
|
25
|
-
relation
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def touch(*names)
|
30
|
-
raise ActiveRecordError, "cannot touch on a new record object" unless persisted?
|
31
|
-
|
32
|
-
attributes = timestamp_attributes_for_update_in_model
|
33
|
-
attributes.concat(names)
|
34
|
-
|
35
|
-
unless attributes.empty?
|
36
|
-
current_time = current_time_from_proper_timezone
|
37
|
-
changes = {}
|
38
|
-
|
39
|
-
attributes.each do |column|
|
40
|
-
column = column.to_s
|
41
|
-
changes[column] = write_attribute(column, current_time)
|
42
|
-
end
|
43
|
-
|
44
|
-
changes[self.class.locking_column] = increment_lock if locking_enabled?
|
45
|
-
|
46
|
-
clear_attribute_changes(changes.keys)
|
47
|
-
primary_key = self.class.primary_key
|
48
|
-
# CPK
|
49
|
-
#self.class.unscoped.where(primary_key => self[primary_key]).update_all(changes) == 1
|
50
|
-
primary_key_predicate = self.class.unscoped.cpk_id_predicate(self.class.arel_table, Array(primary_key), Array(id))
|
51
|
-
self.class.unscoped.where(primary_key_predicate).update_all(changes) == 1
|
52
|
-
else
|
53
|
-
true
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module Persistence
|
3
|
+
def relation_for_destroy
|
4
|
+
# CPK
|
5
|
+
if self.composite?
|
6
|
+
relation = self.class.unscoped
|
7
|
+
|
8
|
+
Array(self.class.primary_key).each_with_index do |key, index|
|
9
|
+
column = self.class.columns_hash[key]
|
10
|
+
substitute = self.class.connection.substitute_at(column, index)
|
11
|
+
relation = relation.where(self.class.arel_table[key].eq(substitute))
|
12
|
+
relation.bind_values += [[column, self[key]]]
|
13
|
+
end
|
14
|
+
|
15
|
+
relation
|
16
|
+
else
|
17
|
+
pk = self.class.primary_key
|
18
|
+
column = self.class.columns_hash[pk]
|
19
|
+
substitute = self.class.connection.substitute_at(column, 0)
|
20
|
+
|
21
|
+
relation = self.class.unscoped.where(
|
22
|
+
self.class.arel_table[pk].eq(substitute))
|
23
|
+
|
24
|
+
relation.bind_values = [[column, id]]
|
25
|
+
relation
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def touch(*names)
|
30
|
+
raise ActiveRecordError, "cannot touch on a new record object" unless persisted?
|
31
|
+
|
32
|
+
attributes = timestamp_attributes_for_update_in_model
|
33
|
+
attributes.concat(names)
|
34
|
+
|
35
|
+
unless attributes.empty?
|
36
|
+
current_time = current_time_from_proper_timezone
|
37
|
+
changes = {}
|
38
|
+
|
39
|
+
attributes.each do |column|
|
40
|
+
column = column.to_s
|
41
|
+
changes[column] = write_attribute(column, current_time)
|
42
|
+
end
|
43
|
+
|
44
|
+
changes[self.class.locking_column] = increment_lock if locking_enabled?
|
45
|
+
|
46
|
+
clear_attribute_changes(changes.keys)
|
47
|
+
primary_key = self.class.primary_key
|
48
|
+
# CPK
|
49
|
+
#self.class.unscoped.where(primary_key => self[primary_key]).update_all(changes) == 1
|
50
|
+
primary_key_predicate = self.class.unscoped.cpk_id_predicate(self.class.arel_table, Array(primary_key), Array(id))
|
51
|
+
self.class.unscoped.where(primary_key_predicate).update_all(changes) == 1
|
52
|
+
else
|
53
|
+
true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
57
|
end
|
@@ -1,68 +1,68 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
class Relation
|
3
|
-
alias :initialize_without_cpk :initialize
|
4
|
-
def initialize(klass, table, values = {})
|
5
|
-
initialize_without_cpk(klass, table, values)
|
6
|
-
add_cpk_support if klass && klass.composite?
|
7
|
-
end
|
8
|
-
|
9
|
-
alias :initialize_copy_without_cpk :initialize_copy
|
10
|
-
def initialize_copy(other)
|
11
|
-
initialize_copy_without_cpk(other)
|
12
|
-
add_cpk_support if klass.composite?
|
13
|
-
end
|
14
|
-
|
15
|
-
def add_cpk_support
|
16
|
-
extend CompositePrimaryKeys::CompositeRelation
|
17
|
-
end
|
18
|
-
|
19
|
-
# CPK adds this so that it finds the Equality nodes beneath the And node:
|
20
|
-
# equalities = where_values.grep(Arel::Nodes::Equality).find_all { |node|
|
21
|
-
# node.left.relation.name == table_name
|
22
|
-
# }
|
23
|
-
alias :where_values_hash_without_cpk :where_values_hash
|
24
|
-
def where_values_hash(relation_table_name = table_name)
|
25
|
-
nodes_from_and = where_values.grep(Arel::Nodes::And).map {|and_node| and_node.children.grep(Arel::Nodes::Equality) }.flatten
|
26
|
-
|
27
|
-
equalities = (nodes_from_and + where_values.grep(Arel::Nodes::Equality)).find_all { |node|
|
28
|
-
node.left.relation.name == relation_table_name
|
29
|
-
}
|
30
|
-
|
31
|
-
binds = Hash[bind_values.find_all(&:first).map { |column, v| [column.name, v] }]
|
32
|
-
|
33
|
-
Hash[equalities.map { |where|
|
34
|
-
name = where.left.name
|
35
|
-
[name, binds.fetch(name.to_s) {
|
36
|
-
case where.right
|
37
|
-
when Array then where.right.map(&:val)
|
38
|
-
else
|
39
|
-
where.right.val
|
40
|
-
end
|
41
|
-
}]
|
42
|
-
}]
|
43
|
-
end
|
44
|
-
|
45
|
-
def _update_record(values, id, id_was)
|
46
|
-
substitutes, binds = substitute_values values
|
47
|
-
|
48
|
-
# CPK
|
49
|
-
um = if self.composite?
|
50
|
-
relation = @klass.unscoped.where(cpk_id_predicate(@klass.arel_table, @klass.primary_key, id_was || id))
|
51
|
-
relation.arel.compile_update(substitutes, @klass.primary_key)
|
52
|
-
else
|
53
|
-
scope = @klass.unscoped
|
54
|
-
|
55
|
-
if @klass.finder_needs_type_condition?
|
56
|
-
scope.unscope!(where: @klass.inheritance_column)
|
57
|
-
end
|
58
|
-
|
59
|
-
scope.where(@klass.arel_table[@klass.primary_key].eq(id_was || id)).arel.compile_update(substitutes, @klass.primary_key)
|
60
|
-
end
|
61
|
-
|
62
|
-
@klass.connection.update(
|
63
|
-
um,
|
64
|
-
'SQL',
|
65
|
-
binds)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
class Relation
|
3
|
+
alias :initialize_without_cpk :initialize
|
4
|
+
def initialize(klass, table, values = {})
|
5
|
+
initialize_without_cpk(klass, table, values)
|
6
|
+
add_cpk_support if klass && klass.composite?
|
7
|
+
end
|
8
|
+
|
9
|
+
alias :initialize_copy_without_cpk :initialize_copy
|
10
|
+
def initialize_copy(other)
|
11
|
+
initialize_copy_without_cpk(other)
|
12
|
+
add_cpk_support if klass.composite?
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_cpk_support
|
16
|
+
extend CompositePrimaryKeys::CompositeRelation
|
17
|
+
end
|
18
|
+
|
19
|
+
# CPK adds this so that it finds the Equality nodes beneath the And node:
|
20
|
+
# equalities = where_values.grep(Arel::Nodes::Equality).find_all { |node|
|
21
|
+
# node.left.relation.name == table_name
|
22
|
+
# }
|
23
|
+
alias :where_values_hash_without_cpk :where_values_hash
|
24
|
+
def where_values_hash(relation_table_name = table_name)
|
25
|
+
nodes_from_and = where_values.grep(Arel::Nodes::And).map {|and_node| and_node.children.grep(Arel::Nodes::Equality) }.flatten
|
26
|
+
|
27
|
+
equalities = (nodes_from_and + where_values.grep(Arel::Nodes::Equality)).find_all { |node|
|
28
|
+
node.left.relation.name == relation_table_name
|
29
|
+
}
|
30
|
+
|
31
|
+
binds = Hash[bind_values.find_all(&:first).map { |column, v| [column.name, v] }]
|
32
|
+
|
33
|
+
Hash[equalities.map { |where|
|
34
|
+
name = where.left.name
|
35
|
+
[name, binds.fetch(name.to_s) {
|
36
|
+
case where.right
|
37
|
+
when Array then where.right.map(&:val)
|
38
|
+
else
|
39
|
+
where.right.val
|
40
|
+
end
|
41
|
+
}]
|
42
|
+
}]
|
43
|
+
end
|
44
|
+
|
45
|
+
def _update_record(values, id, id_was)
|
46
|
+
substitutes, binds = substitute_values values
|
47
|
+
|
48
|
+
# CPK
|
49
|
+
um = if self.composite?
|
50
|
+
relation = @klass.unscoped.where(cpk_id_predicate(@klass.arel_table, @klass.primary_key, id_was || id))
|
51
|
+
relation.arel.compile_update(substitutes, @klass.primary_key)
|
52
|
+
else
|
53
|
+
scope = @klass.unscoped
|
54
|
+
|
55
|
+
if @klass.finder_needs_type_condition?
|
56
|
+
scope.unscope!(where: @klass.inheritance_column)
|
57
|
+
end
|
58
|
+
|
59
|
+
scope.where(@klass.arel_table[@klass.primary_key].eq(id_was || id)).arel.compile_update(substitutes, @klass.primary_key)
|
60
|
+
end
|
61
|
+
|
62
|
+
@klass.connection.update(
|
63
|
+
um,
|
64
|
+
'SQL',
|
65
|
+
binds)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|