composite_primary_keys 4.1.2 → 5.0.0.rc1

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.
@@ -26,7 +26,7 @@ $:.unshift(File.dirname(__FILE__)) unless
26
26
 
27
27
  unless defined?(ActiveRecord)
28
28
  require 'rubygems'
29
- gem 'activerecord', '~> 3.1.0'
29
+ gem 'activerecord', '~> 3.2.0.rc2'
30
30
  require 'active_record'
31
31
  end
32
32
 
@@ -34,6 +34,7 @@ end
34
34
  require 'active_record/fixtures'
35
35
  require 'active_record/persistence'
36
36
  require 'active_record/relation'
37
+ require 'active_record/sanitization'
37
38
 
38
39
  require 'active_record/associations/association'
39
40
  require 'active_record/associations/association_scope'
@@ -68,6 +69,7 @@ require 'composite_primary_keys/composite_predicates'
68
69
  require 'composite_primary_keys/fixtures'
69
70
  require 'composite_primary_keys/persistence'
70
71
  require 'composite_primary_keys/relation'
72
+ require 'composite_primary_keys/sanitization'
71
73
  require 'composite_primary_keys/version'
72
74
 
73
75
  require 'composite_primary_keys/associations/association'
@@ -2,50 +2,26 @@ module ActiveRecord
2
2
  module AttributeMethods
3
3
  module Read
4
4
  module ClassMethods
5
- def define_read_method(method_name, attr_name, column)
6
- cast_code = column.type_cast_code('v')
5
+ def internal_attribute_access_code(attr_name, cast_code)
7
6
  # CPK - this is a really horrid hack, needed to get
8
7
  # right class namespace :(
9
8
  if cast_code.match(/^ActiveRecord/)
10
9
  cast_code = "::#{cast_code}"
11
10
  end
12
-
13
- access_code = "(v=@attributes['#{attr_name}']) && #{cast_code}"
11
+ access_code = "(v=@attributes[attr_name]) && #{cast_code}"
14
12
 
15
13
  # CPK
16
- # unless attr_name.to_s == self.primary_key.to_s
17
- # access_code.insert(0, "missing_attribute('#{attr_name}', caller) unless @attributes.has_key?('#{attr_name}'); ")
18
- # end
14
+ #unless attr_name == primary_key
19
15
  primary_keys = Array(self.primary_key)
20
-
21
16
  unless primary_keys.include?(attr_name.to_s)
22
- access_code = access_code.insert(0, "missing_attribute('#{attr_name}', caller) unless @attributes.has_key?('#{attr_name}'); ")
17
+ access_code.insert(0, "missing_attribute(attr_name, caller) unless @attributes.has_key?(attr_name); ")
23
18
  end
24
19
 
25
20
  if cache_attribute?(attr_name)
26
- access_code = "@attributes_cache['#{attr_name}'] ||= (#{access_code})"
21
+ access_code = "@attributes_cache[attr_name] ||= (#{access_code})"
27
22
  end
28
23
 
29
- # Where possible, generate the method by evalling a string, as this will result in
30
- # faster accesses because it avoids the block eval and then string eval incurred
31
- # by the second branch.
32
- #
33
- # The second, slower, branch is necessary to support instances where the database
34
- # returns columns with extra stuff in (like 'my_column(omg)').
35
- if method_name =~ ActiveModel::AttributeMethods::COMPILABLE_REGEXP
36
- generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__
37
- def _#{method_name}
38
- #{access_code}
39
- end
40
-
41
- alias #{method_name} _#{method_name}
42
- STR
43
- else
44
- generated_attribute_methods.module_eval do
45
- define_method("_#{method_name}") { eval(access_code) }
46
- alias_method(method_name, "_#{method_name}")
47
- end
48
- end
24
+ "attr_name = '#{attr_name}'; #{access_code}"
49
25
  end
50
26
  end
51
27
 
@@ -53,30 +29,8 @@ module ActiveRecord
53
29
  # CPK
54
30
  if attr_name.kind_of?(Array)
55
31
  attr_name.map {|name| read_attribute(name)}.to_composite_keys
56
- elsif respond_to? "_#{attr_name}"
57
- send "_#{attr_name}" if @attributes.has_key?(attr_name.to_s)
58
32
  else
59
- _read_attribute attr_name
60
- end
61
- end
62
-
63
-
64
- def _read_attribute(attr_name)
65
- attr_name = attr_name.to_s
66
- # CPK
67
- # attr_name = self.class.primary_key if attr_name == 'id'
68
- attr_name = self.class.primary_key if (attr_name == 'id' and !self.composite?)
69
- value = @attributes[attr_name]
70
- unless value.nil?
71
- if column = column_for_attribute(attr_name)
72
- if unserializable_attribute?(attr_name, column)
73
- unserialize_attribute(attr_name)
74
- else
75
- column.type_cast(value)
76
- end
77
- else
78
- value
79
- end
33
+ self.class.type_cast_attribute(attr_name, @attributes, @attributes_cache)
80
34
  end
81
35
  end
82
36
  end
@@ -85,4 +39,4 @@ end
85
39
 
86
40
  ActiveRecord::Base.class_eval do
87
41
  alias :[] :read_attribute
88
- end
42
+ end
@@ -12,13 +12,15 @@ module ActiveRecord
12
12
  else
13
13
  attr_name = attr_name.to_s
14
14
  # CPK
15
- # attr_name = self.class.primary_key if attr_name == 'id'
16
- attr_name = self.class.primary_key if (attr_name == 'id' and !self.composite?)
15
+ # attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key
16
+ attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key && !self.composite?
17
17
  @attributes_cache.delete(attr_name)
18
- if (column = column_for_attribute(attr_name)) && column.number?
19
- @attributes[attr_name] = convert_number_column_value(value)
18
+ column = column_for_attribute(attr_name)
19
+
20
+ if column || @attributes.has_key?(attr_name)
21
+ @attributes[attr_name] = type_cast_attribute_for_write(column, value)
20
22
  else
21
- @attributes[attr_name] = value
23
+ raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{attr_name}'"
22
24
  end
23
25
  end
24
26
  end
@@ -26,8 +28,7 @@ module ActiveRecord
26
28
  end
27
29
  end
28
30
 
29
- #ActiveRecord::Base.class_eval do
30
- # alias :[]= :write_attribute
31
- # alias :raw_write_attribute :write_attribute
32
- # public :[]=
33
- #end
31
+ ActiveRecord::Base.class_eval do
32
+ alias :[]= :write_attribute
33
+ public :[]=
34
+ end
@@ -33,6 +33,31 @@ module ActiveRecord
33
33
  self.class.composite?
34
34
  end
35
35
 
36
+ def initialize_dup(other)
37
+ cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast)
38
+ # CPK
39
+ # cloned_attributes.delete(self.class.primary_key)
40
+ Array(self.class.primary_key).each {|key| cloned_attributes.delete(key.to_s)}
41
+
42
+ @attributes = cloned_attributes
43
+
44
+ _run_after_initialize_callbacks if respond_to?(:_run_after_initialize_callbacks)
45
+
46
+ @changed_attributes = {}
47
+ self.class.column_defaults.each do |attr, orig_value|
48
+ @changed_attributes[attr] = orig_value if field_changed?(attr, orig_value, @attributes[attr])
49
+ end
50
+
51
+ @aggregation_cache = {}
52
+ @association_cache = {}
53
+ @attributes_cache = {}
54
+ @new_record = true
55
+
56
+ ensure_proper_type
57
+ populate_with_current_scope_attributes
58
+ super
59
+ end
60
+
36
61
  module CompositeClassMethods
37
62
  def primary_key
38
63
  primary_keys
@@ -75,12 +100,6 @@ module ActiveRecord
75
100
  end
76
101
  end
77
102
 
78
- def quoted_id #:nodoc:
79
- [self.class.primary_keys, ids].
80
- transpose.
81
- map {|attr_name,id| quote_value(id, column_for_attribute(attr_name))}
82
- end
83
-
84
103
  # Sets the primary ID.
85
104
  def id=(ids)
86
105
  ids = ids.split(CompositePrimaryKeys::ID_SEP) if ids.is_a?(String)
@@ -96,31 +115,6 @@ module ActiveRecord
96
115
  ids.is_a?(Array) ? super(comparison_object) && ids.all? {|id| id.present?} : super(comparison_object)
97
116
  end
98
117
 
99
- def initialize_dup(other)
100
- cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast)
101
- # CPK
102
- #cloned_attributes.delete(self.class.primary_key)
103
- self.class.primary_key.each {|key| cloned_attributes.delete(key.to_s)}
104
-
105
- @attributes = cloned_attributes
106
-
107
- _run_after_initialize_callbacks if respond_to?(:_run_after_initialize_callbacks)
108
-
109
- @changed_attributes = {}
110
- attributes_from_column_definition.each do |attr, orig_value|
111
- @changed_attributes[attr] = orig_value if field_changed?(attr, orig_value, @attributes[attr])
112
- end
113
-
114
- @aggregation_cache = {}
115
- @association_cache = {}
116
- @attributes_cache = {}
117
- @new_record = true
118
-
119
- ensure_proper_type
120
- populate_with_current_scope_attributes
121
- clear_timestamp_attributes
122
- end
123
-
124
118
  def can_change_primary_key_values?
125
119
  false
126
120
  end
@@ -2,10 +2,11 @@ module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  class PostgreSQLAdapter
4
4
  def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
5
- # Extract the table from the insert sql. Yuck.
6
- _, table = extract_schema_and_table(sql.split(" ", 4)[2])
7
-
8
- pk ||= primary_key(table)
5
+ unless pk
6
+ # Extract the table from the insert sql. Yuck.
7
+ table_ref = extract_table_ref_from_insert_sql(sql)
8
+ pk = primary_key(table_ref) if table_ref
9
+ end
9
10
 
10
11
  if pk
11
12
  # CPK
@@ -19,9 +20,9 @@ module ActiveRecord
19
20
 
20
21
  def sql_for_insert(sql, pk, id_value, sequence_name, binds)
21
22
  unless pk
22
- _, table = extract_schema_and_table(sql.split(" ", 4)[2])
23
-
24
- pk = primary_key(table)
23
+ # Extract the table from the insert sql. Yuck.
24
+ table_ref = extract_table_ref_from_insert_sql(sql)
25
+ pk = primary_key(table_ref) if table_ref
25
26
  end
26
27
 
27
28
  # CPK
@@ -0,0 +1,15 @@
1
+ module ActiveRecord
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))
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,8 +1,8 @@
1
1
  module CompositePrimaryKeys
2
2
  module VERSION
3
- MAJOR = 4
4
- MINOR = 1
5
- TINY = 2
6
- STRING = [MAJOR, MINOR, TINY].join('.')
3
+ MAJOR = 5
4
+ MINOR = 0
5
+ TINY = 0
6
+ STRING = [MAJOR, MINOR, TINY, 'rc1'].join('.')
7
7
  end
8
8
  end
@@ -7,7 +7,9 @@ gem 'syntax'
7
7
  require 'redcloth'
8
8
  require 'syntax/convertors/html'
9
9
  require 'erb'
10
- require File.dirname(__FILE__) + '/../lib/composite_primary_keys/version.rb'
10
+
11
+ version_path = File.join(File.dirname(__FILE__), '..', 'lib', 'composite_primary_keys', 'version.rb')
12
+ require File.expand_path(version_path)
11
13
 
12
14
  version = CompositePrimaryKeys::VERSION::STRING
13
15
  download = 'http://rubygems.org/gems/composite_primary_keys'
@@ -18,10 +20,14 @@ class Fixnum
18
20
  return 'th' if (10..19).include?(self % 100)
19
21
  # others
20
22
  case self % 10
21
- when 1: return 'st'
22
- when 2: return 'nd'
23
- when 3: return 'rd'
24
- else return 'th'
23
+ when 1
24
+ return 'st'
25
+ when 2
26
+ return 'nd'
27
+ when 3
28
+ return 'rd'
29
+ else
30
+ return 'th'
25
31
  end
26
32
  end
27
33
  end
@@ -5,7 +5,9 @@ require 'redcloth'
5
5
  require 'syntax/convertors/html'
6
6
  require 'erb'
7
7
  require 'active_support'
8
- require File.dirname(__FILE__) + '/../lib/composite_primary_keys/version.rb'
8
+
9
+ version_path = File.join(File.dirname(__FILE__), '..', 'lib', 'composite_primary_keys', 'version.rb')
10
+ require File.expand_path(version_path)
9
11
 
10
12
  version = CompositePrimaryKeys::VERSION::STRING
11
13
  download = 'http://rubygems.org/gems/composite_primary_keys'
@@ -16,10 +18,14 @@ class Fixnum
16
18
  return 'th' if (10..19).include?(self % 100)
17
19
  # others
18
20
  case self % 10
19
- when 1: return 'st'
20
- when 2: return 'nd'
21
- when 3: return 'rd'
22
- else return 'th'
21
+ when 1
22
+ return 'st'
23
+ when 2
24
+ return 'nd'
25
+ when 3
26
+ return 'rd'
27
+ else
28
+ return 'th'
23
29
  end
24
30
  end
25
31
  end
@@ -2,7 +2,6 @@ PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
2
2
 
3
3
  require "pp"
4
4
  require "test/unit"
5
- require File.expand_path('../hash_tricks', __FILE__)
6
5
 
7
6
  # To make debugging easier, test within this source tree versus an installed gem
8
7
  $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
@@ -43,28 +43,18 @@ class TestAttributes < ActiveSupport::TestCase
43
43
  end
44
44
 
45
45
  def test_brackets_foreign_key_assignment
46
- flat = tariffs(:flat)
47
- second_free = tariffs(:free)
48
- second_free_fk = [:tariff_id, :tariff_start_date]
49
-
50
- second_free[key = second_free_fk] = flat.id
51
- compare_indexes(flat, flat.class.primary_key, second_free, second_free_fk)
52
- assert_equal flat.id, second_free[key]
53
-
54
- second_free[key = second_free_fk.to_composite_keys] = flat.id
55
- assert_equal flat.id, second_free[key]
56
- compare_indexes(flat, flat.class.primary_key, second_free, second_free_fk)
57
-
58
- second_free[key = second_free_fk.to_composite_keys.to_s] = flat.id
59
- assert_equal flat.id, second_free[key]
60
- compare_indexes(flat, flat.class.primary_key, second_free, second_free_fk)
46
+ tarrif = tariffs(:flat)
47
+ product_tariff = product_tariffs(:first_flat)
48
+ compare_indexes(tarrif, tarrif.class.primary_key, product_tariff, [:tariff_id, :tariff_start_date])
61
49
  end
62
50
 
63
51
  private
64
52
 
65
53
  def compare_indexes(obj1, indexes1, obj2, indexes2)
66
54
  indexes1.length.times do |key_index|
67
- assert_equal(obj1[indexes1[key_index].to_s], obj2[indexes2[key_index].to_s])
55
+ key1 = indexes1[key_index]
56
+ key2 = indexes2[key_index]
57
+ assert_equal(obj1[key1], obj2[key2])
68
58
  end
69
59
  end
70
60
  end
@@ -36,7 +36,7 @@ class TestCreate < ActiveSupport::TestCase
36
36
  def test_create_no_id
37
37
  testing_with do
38
38
  begin
39
- @obj = @klass.create(@klass_info[:create].block(@klass.primary_key))
39
+ @obj = @klass.create(@klass_info[:create].except(@klass.primary_key))
40
40
  @successful = !composite?
41
41
  rescue ActiveRecord::CompositeKeyError
42
42
  @successful = false
@@ -21,7 +21,9 @@ class TestClone < ActiveSupport::TestCase
21
21
  def test_dup
22
22
  testing_with do
23
23
  clone = @first.dup
24
- assert_equal(@first.attributes.block(@klass.primary_key), clone.attributes)
24
+
25
+ remove_keys = Array(@klass.primary_key).map &:to_s
26
+ assert_equal(@first.attributes.except(*remove_keys), clone.attributes)
25
27
 
26
28
  if composite?
27
29
  @klass.primary_key.each do |key|
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: composite_primary_keys
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.2
5
- prerelease:
4
+ version: 5.0.0.rc1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Dr Nic Williams
@@ -10,19 +10,19 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-01-12 00:00:00.000000000 Z
13
+ date: 2012-01-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
17
- requirement: &22966128 !ruby/object:Gem::Requirement
17
+ requirement: &24769260 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
21
21
  - !ruby/object:Gem::Version
22
- version: '3.1'
22
+ version: 3.2.0.rc2
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *22966128
25
+ version_requirements: *24769260
26
26
  description: Composite key support for ActiveRecord 3
27
27
  email:
28
28
  - drnicwilliams@gmail.com
@@ -63,6 +63,7 @@ files:
63
63
  - lib/composite_primary_keys/relation/finder_methods.rb
64
64
  - lib/composite_primary_keys/relation/query_methods.rb
65
65
  - lib/composite_primary_keys/relation.rb
66
+ - lib/composite_primary_keys/sanitization.rb
66
67
  - lib/composite_primary_keys/validations/uniqueness.rb
67
68
  - lib/composite_primary_keys/version.rb
68
69
  - lib/composite_primary_keys.rb
@@ -146,7 +147,6 @@ files:
146
147
  - test/fixtures/tariffs.yml
147
148
  - test/fixtures/user.rb
148
149
  - test/fixtures/users.yml
149
- - test/hash_tricks.rb
150
150
  - test/plugins/pagination.rb
151
151
  - test/plugins/pagination_helper.rb
152
152
  - test/README_tests.txt
@@ -187,12 +187,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
187
187
  required_rubygems_version: !ruby/object:Gem::Requirement
188
188
  none: false
189
189
  requirements:
190
- - - ! '>='
190
+ - - ! '>'
191
191
  - !ruby/object:Gem::Version
192
- version: '0'
192
+ version: 1.3.1
193
193
  requirements: []
194
194
  rubyforge_project: compositekeys
195
- rubygems_version: 1.8.10
195
+ rubygems_version: 1.8.15
196
196
  signing_key:
197
197
  specification_version: 3
198
198
  summary: Composite key support for ActiveRecord
@@ -200,7 +200,6 @@ test_files:
200
200
  - test/abstract_unit.rb
201
201
  - test/db_test.rb
202
202
  - test/debug.log
203
- - test/hash_tricks.rb
204
203
  - test/README_tests.txt
205
204
  - test/setup.rb
206
205
  - test/test_associations.rb
@@ -1,34 +0,0 @@
1
- # From:
2
- # http://www.bigbold.com/snippets/posts/show/2178
3
- # http://blog.caboo.se/articles/2006/06/11/stupid-hash-tricks
4
- #
5
- # An example utilisation of these methods in a controller is:
6
- # def some_action
7
- # # some script kiddie also passed in :bee, which we don't want tampered with _here_.
8
- # @model = Model.create(params.pass(:foo, :bar))
9
- # end
10
- class Hash
11
-
12
- # lets through the keys in the argument
13
- # >> {:one => 1, :two => 2, :three => 3}.pass(:one)
14
- # => {:one=>1}
15
- def pass(*keys)
16
- keys = keys.first if keys.first.is_a?(Array)
17
- tmp = self.clone
18
- tmp.delete_if {|k,v| ! keys.include?(k.to_sym) }
19
- tmp.delete_if {|k,v| ! keys.include?(k.to_s) }
20
- tmp
21
- end
22
-
23
- # blocks the keys in the arguments
24
- # >> {:one => 1, :two => 2, :three => 3}.block(:one)
25
- # => {:two=>2, :three=>3}
26
- def block(*keys)
27
- keys = keys.first if keys.first.is_a?(Array)
28
- tmp = self.clone
29
- tmp.delete_if {|k,v| keys.include?(k.to_sym) }
30
- tmp.delete_if {|k,v| keys.include?(k.to_s) }
31
- tmp
32
- end
33
-
34
- end