composite_primary_keys 4.1.2 → 5.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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