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.
@@ -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
- # CPK
8
- # order = order_clause.empty? ?
9
- # "#{table_name}.#{primary_key} DESC" :
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
- order = unless order_clause.empty?
13
- reverse_sql_order(order_clause).join(', ')
14
- else
15
- klass.primary_key.map do |key|
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
- except(:order).order(Arel.sql(order))
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
- def quoted_id
4
- # CPK
5
- #quote_value(id, column_for_attribute(self.class.primary_key))
6
- if self.composite?
7
- [self.class.primary_keys, ids].
8
- transpose.
9
- map {|attr_name,id| quote_value(id, column_for_attribute(attr_name))}
10
- else
11
- quote_value(id, column_for_attribute(self.class.primary_key))
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
@@ -2,7 +2,7 @@ module CompositePrimaryKeys
2
2
  module VERSION
3
3
  MAJOR = 5
4
4
  MINOR = 0
5
- TINY = 10
5
+ TINY = 11
6
6
  STRING = [MAJOR, MINOR, TINY].join('.')
7
7
  end
8
8
  end
@@ -25,6 +25,8 @@ create table tariffs (
25
25
  tariff_id int not null,
26
26
  start_date date not null,
27
27
  amount integer(11) default null,
28
+ created_at timestamp,
29
+ updated_at timestamp,
28
30
  primary key (tariff_id, start_date)
29
31
  );
30
32
 
@@ -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
 
@@ -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
@@ -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'
@@ -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
- end
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.10
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: 2012-11-21 00:00:00.000000000 Z
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