composite_primary_keys 5.0.10 → 5.0.11
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +7 -0
- data/lib/composite_primary_keys/associations/has_many_association.rb +6 -0
- data/lib/composite_primary_keys/relation/query_methods.rb +21 -18
- data/lib/composite_primary_keys/sanitization.rb +47 -10
- data/lib/composite_primary_keys/version.rb +1 -1
- data/test/fixtures/db_definitions/mysql.sql +2 -0
- data/test/fixtures/reference_type.rb +2 -1
- data/test/test_associations.rb +8 -0
- data/test/test_nested_attributes.rb +39 -0
- data/test/test_touch.rb +2 -2
- data/test/test_update.rb +17 -7
- metadata +4 -2
data/History.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 5.0.11 2013-01-19
|
2
|
+
* Patch HasManyAssociation foreign_key_present? method to work with array of keys (tbeauvais)
|
3
|
+
* Patch reverse_sql_order method to break apart CPKs (tbeauvais)
|
4
|
+
* Add test and fix for nested_attributes update (Dinshaw Gobhai)
|
5
|
+
* Add test and fix for to_sym exception (Dinshaw Gobhai)
|
6
|
+
* Add missing timestamp columns for mysql test_touch.rb (Dinshaw Gobhai)
|
7
|
+
|
1
8
|
== 5.0.10 2012-11-21
|
2
9
|
* ActiveRecord 3.2.9 compatability (Tom Hughes, Chris Heald, Jack Tang)
|
3
10
|
* Add support for find_in_batches (Charlie Savage)
|
@@ -37,6 +37,12 @@ module ActiveRecord
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
40
|
+
|
41
|
+
def foreign_key_present?
|
42
|
+
# CPK
|
43
|
+
# owner.attribute_present?(reflection.association_primary_key)
|
44
|
+
reflection.association_primary_key.all?{ |key| owner.attribute_present?(key) }
|
45
|
+
end
|
40
46
|
end
|
41
47
|
end
|
42
48
|
end
|
@@ -1,24 +1,27 @@
|
|
1
|
-
module CompositePrimaryKeys
|
2
|
-
module ActiveRecord
|
3
|
-
module QueryMethods
|
4
|
-
def reverse_order
|
5
|
-
order_clause = arel.order_clauses
|
1
|
+
module CompositePrimaryKeys::ActiveRecord::QueryMethods
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
# reverse_sql_order(order_clause).join(', ')
|
3
|
+
def reverse_sql_order(order_query)
|
4
|
+
# CPK
|
5
|
+
# order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty?
|
11
6
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
"#{table_name}.#{key} DESC"
|
17
|
-
end.join(", ")
|
18
|
-
end
|
7
|
+
# break apart CPKs
|
8
|
+
order_query = primary_key.map do |key|
|
9
|
+
"#{quoted_table_name}.#{connection.quote_column_name(key)} ASC"
|
10
|
+
end if order_query.empty?
|
19
11
|
|
20
|
-
|
12
|
+
order_query.map do |o|
|
13
|
+
case o
|
14
|
+
when Arel::Nodes::Ordering
|
15
|
+
o.reverse
|
16
|
+
when String, Symbol
|
17
|
+
o.to_s.split(',').collect do |s|
|
18
|
+
s.strip!
|
19
|
+
s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC')
|
20
|
+
end
|
21
|
+
else
|
22
|
+
o
|
21
23
|
end
|
22
|
-
end
|
24
|
+
end.flatten
|
23
25
|
end
|
26
|
+
|
24
27
|
end
|
@@ -1,15 +1,52 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Sanitization
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
module ClassMethods
|
4
|
+
protected
|
5
|
+
# Accepts a hash of SQL conditions and replaces those attributes
|
6
|
+
# that correspond to a +composed_of+ relationship with their expanded
|
7
|
+
# aggregate attribute values.
|
8
|
+
# Given:
|
9
|
+
# class Person < ActiveRecord::Base
|
10
|
+
# composed_of :address, class_name: "Address",
|
11
|
+
# mapping: [%w(address_street street), %w(address_city city)]
|
12
|
+
# end
|
13
|
+
# Then:
|
14
|
+
# { address: Address.new("813 abc st.", "chicago") }
|
15
|
+
# # => { address_street: "813 abc st.", address_city: "chicago" }
|
16
|
+
def expand_hash_conditions_for_aggregates(attrs)
|
17
|
+
expanded_attrs = {}
|
18
|
+
attrs.each do |attr, value|
|
19
|
+
if attr.is_a?(CompositePrimaryKeys::CompositeKeys)
|
20
|
+
attr.each_with_index do |key,i|
|
21
|
+
expanded_attrs[key] = value.flatten[i]
|
22
|
+
end
|
23
|
+
elsif aggregation = reflect_on_aggregation(attr.to_sym)
|
24
|
+
mapping = aggregation.mapping
|
25
|
+
mapping.each do |field_attr, aggregate_attr|
|
26
|
+
if mapping.size == 1 && !value.respond_to?(aggregate_attr)
|
27
|
+
expanded_attrs[field_attr] = value
|
28
|
+
else
|
29
|
+
expanded_attrs[field_attr] = value.send(aggregate_attr)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
else
|
33
|
+
expanded_attrs[attr] = value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
expanded_attrs
|
37
|
+
end
|
38
|
+
|
39
|
+
def quoted_id
|
40
|
+
# CPK
|
41
|
+
#quote_value(id, column_for_attribute(self.class.primary_key))
|
42
|
+
if self.composite?
|
43
|
+
[self.class.primary_keys, ids].
|
44
|
+
transpose.
|
45
|
+
map {|attr_name,id| quote_value(id, column_for_attribute(attr_name))}
|
46
|
+
else
|
47
|
+
quote_value(id, column_for_attribute(self.class.primary_key))
|
48
|
+
end
|
12
49
|
end
|
13
50
|
end
|
14
51
|
end
|
15
|
-
end
|
52
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
class ReferenceType < ActiveRecord::Base
|
2
2
|
self.primary_key = :reference_type_id
|
3
3
|
has_many :reference_codes, :foreign_key => "reference_type_id", :dependent => :destroy
|
4
|
-
|
4
|
+
accepts_nested_attributes_for :reference_codes
|
5
|
+
|
5
6
|
validates_presence_of :type_label, :abbreviation
|
6
7
|
validates_uniqueness_of :type_label
|
7
8
|
|
data/test/test_associations.rb
CHANGED
@@ -269,4 +269,12 @@ class TestAssociations < ActiveSupport::TestCase
|
|
269
269
|
assert_equal(1, memberships.length)
|
270
270
|
assert_equal([1,1], memberships[0].id)
|
271
271
|
end
|
272
|
+
|
273
|
+
def test_foreign_key_present_with_null_association_ids
|
274
|
+
group = Group.new
|
275
|
+
group.memberships.build
|
276
|
+
associations = group.association_cache[:memberships]
|
277
|
+
assert_equal(false, associations.send('foreign_key_present?'))
|
278
|
+
end
|
279
|
+
|
272
280
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path('../abstract_unit', __FILE__)
|
2
|
+
|
3
|
+
# Testing the find action on composite ActiveRecords with two primary keys
|
4
|
+
class TestNestedAttributes < ActiveSupport::TestCase
|
5
|
+
fixtures :reference_types
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@reference_type = ReferenceType.first
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_nested_atttribute_create
|
12
|
+
code_id = 1001
|
13
|
+
@reference_type.update_attribute :reference_codes_attributes, [{
|
14
|
+
:reference_code => code_id,
|
15
|
+
:code_label => 'XX',
|
16
|
+
:abbreviation => 'Xx'
|
17
|
+
}]
|
18
|
+
assert_not_nil ReferenceCode.find_by_reference_code(code_id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_nested_atttribute_update
|
22
|
+
code_id = 1002
|
23
|
+
@reference_type.update_attribute :reference_codes_attributes, [{
|
24
|
+
:reference_code => code_id,
|
25
|
+
:code_label => 'XX',
|
26
|
+
:abbreviation => 'Xx'
|
27
|
+
}]
|
28
|
+
reference_code = ReferenceCode.find_by_reference_code(code_id)
|
29
|
+
cpk = CompositePrimaryKeys::CompositeKeys[@reference_type.reference_type_id, code_id]
|
30
|
+
@reference_type.update_attribute :reference_codes_attributes, [{
|
31
|
+
:id => cpk,
|
32
|
+
:code_label => 'AAA',
|
33
|
+
:abbreviation => 'Aaa'
|
34
|
+
}]
|
35
|
+
reference_code = ReferenceCode.find_by_reference_code(code_id)
|
36
|
+
assert_kind_of(ReferenceCode, reference_code)
|
37
|
+
assert_equal(reference_code.code_label, 'AAA')
|
38
|
+
end
|
39
|
+
end
|
data/test/test_touch.rb
CHANGED
@@ -9,10 +9,10 @@ class TestTouch < ActiveSupport::TestCase
|
|
9
9
|
tariff = tariffs(:flat)
|
10
10
|
previous_amount = tariff.amount
|
11
11
|
previously_updated_at = tariff.updated_at
|
12
|
-
|
12
|
+
|
13
13
|
tariff.amount = previous_amount + 1
|
14
14
|
tariff.touch
|
15
|
-
|
15
|
+
sleep 0.1
|
16
16
|
assert_not_equal previously_updated_at, tariff.updated_at
|
17
17
|
assert_equal previous_amount + 1, tariff.amount
|
18
18
|
assert tariff.amount_changed?, 'tarif amount should have changed'
|
data/test/test_update.rb
CHANGED
@@ -2,30 +2,30 @@ require File.expand_path('../abstract_unit', __FILE__)
|
|
2
2
|
|
3
3
|
class TestUpdate < ActiveSupport::TestCase
|
4
4
|
fixtures :reference_types, :reference_codes
|
5
|
-
|
5
|
+
|
6
6
|
CLASSES = {
|
7
7
|
:single => {
|
8
8
|
:class => ReferenceType,
|
9
9
|
:primary_keys => :reference_type_id,
|
10
10
|
:update => { :description => 'RT Desc' },
|
11
11
|
},
|
12
|
-
:dual => {
|
12
|
+
:dual => {
|
13
13
|
:class => ReferenceCode,
|
14
14
|
:primary_keys => [:reference_type_id, :reference_code],
|
15
15
|
:update => { :description => 'RT Desc' },
|
16
16
|
},
|
17
17
|
}
|
18
|
-
|
18
|
+
|
19
19
|
def setup
|
20
20
|
self.class.classes = CLASSES
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def test_setup
|
24
24
|
testing_with do
|
25
25
|
assert_not_nil @klass_info[:update]
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def test_update_attributes
|
30
30
|
testing_with do
|
31
31
|
assert(@first.update_attributes(@klass_info[:update]))
|
@@ -35,7 +35,7 @@ class TestUpdate < ActiveSupport::TestCase
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def test_update_primary_key
|
40
40
|
obj = ReferenceCode.find([1,1])
|
41
41
|
obj.reference_type_id = 2
|
@@ -59,4 +59,14 @@ class TestUpdate < ActiveSupport::TestCase
|
|
59
59
|
assert(obj.reload)
|
60
60
|
assert_equal('b', obj.abbreviation)
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
|
+
def test_update_all
|
64
|
+
assert_nothing_raised do
|
65
|
+
refrence_code = ReferenceCode.create
|
66
|
+
primary_key = refrence_code.class.primary_key
|
67
|
+
ReferenceCode.update_all(
|
68
|
+
{description: 'random value'},
|
69
|
+
{primary_key => refrence_code[primary_key]})
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: composite_primary_keys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.
|
4
|
+
version: 5.0.11
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-01-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -183,6 +183,7 @@ files:
|
|
183
183
|
- test/test_habtm.rb
|
184
184
|
- test/test_ids.rb
|
185
185
|
- test/test_miscellaneous.rb
|
186
|
+
- test/test_nested_attributes.rb
|
186
187
|
- test/test_pagination.rb
|
187
188
|
- test/test_polymorphic.rb
|
188
189
|
- test/test_predicates.rb
|
@@ -237,6 +238,7 @@ test_files:
|
|
237
238
|
- test/test_habtm.rb
|
238
239
|
- test/test_ids.rb
|
239
240
|
- test/test_miscellaneous.rb
|
241
|
+
- test/test_nested_attributes.rb
|
240
242
|
- test/test_pagination.rb
|
241
243
|
- test/test_polymorphic.rb
|
242
244
|
- test/test_predicates.rb
|