composite_primary_keys 3.1.6 → 3.1.7

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.
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ == 3.1.7 2011-05-19
2
+ * Support regular AR models having one or many composite models (Jacques Fuentes)
3
+ * Minor test cleanup
4
+ * Make version requirements more explicit
5
+ * Remove Arel extensions used for calculations
6
+ * Fix test that included wrong error constant
7
+
8
+
1
9
  == 3.1.6 2011-04-03
2
10
  * Updated belongs_to association to be a bit more flexible with non-CPK
3
11
  base models (Jacques Fuentes)
@@ -5,12 +13,14 @@
5
13
  * Fix write issue when one of they keys in a composite key is
6
14
  called id (Tom Hughes)
7
15
 
16
+
8
17
  == 3.1.5 2011-03-24
9
18
  * Fix simple calculation methods
10
19
  * Fix instantiation of cpk records via associations.
11
20
  * Fix Relation#delete
12
21
  * Fix Relation#destroy
13
22
 
23
+
14
24
  == 3.1.4 2011-03-06
15
25
  * Support ActiveRecord 3.0.5 (interpolate_sql was removed and
16
26
  replaced by interpolate_and_sanitize_sql)
@@ -25,12 +25,9 @@ $:.unshift(File.dirname(__FILE__)) unless
25
25
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
26
26
 
27
27
  unless defined?(ActiveRecord)
28
- begin
29
- require 'active_record'
30
- rescue LoadError
31
- require 'rubygems'
32
- gem 'active_record'
33
- end
28
+ gem 'arel', '~> 2.0.0'
29
+ gem 'activerecord', '>= 3.0.5', '~> 3.0.0'
30
+ require 'active_record'
34
31
  end
35
32
 
36
33
  require 'active_record/associations.rb'
@@ -49,7 +46,6 @@ require 'active_record/relation/query_methods'
49
46
  require 'active_record/attribute_methods/primary_key'
50
47
  require 'active_record/fixtures'
51
48
 
52
- require 'composite_primary_keys/arel_extensions'
53
49
  require 'composite_primary_keys/composite_arrays'
54
50
  require 'composite_primary_keys/associations'
55
51
  require 'composite_primary_keys/associations/association_proxy'
@@ -30,4 +30,4 @@ module ActiveRecord
30
30
  end
31
31
  end
32
32
  end
33
- end
33
+ end
@@ -22,6 +22,14 @@ module ActiveRecord
22
22
  construct_counter_sql
23
23
  end
24
24
 
25
+ def owner_quoted_id
26
+ if (keys = @reflection.options[:primary_key])
27
+ keys.is_a?(Array) ? keys.collect {|k| quote_value(@owner.send(k)) } : quote_value(@owner.send(keys))
28
+ else
29
+ @owner.quoted_id
30
+ end
31
+ end
32
+
25
33
  def delete_records(records)
26
34
  case @reflection.options[:dependent]
27
35
  when :destroy
@@ -70,4 +78,4 @@ module ActiveRecord
70
78
  end
71
79
  end
72
80
  end
73
- end
81
+ end
@@ -14,6 +14,14 @@ module ActiveRecord
14
14
  end
15
15
  @finder_sql << " AND (#{conditions})" if conditions
16
16
  end
17
+
18
+ def owner_quoted_id
19
+ if (keys = @reflection.options[:primary_key])
20
+ keys.is_a?(Array) ? keys.collect {|k| @owner.class.quote_value(@owner.send(k)) } : @owner.class.quote_value(@owner.send(keys))
21
+ else
22
+ @owner.quoted_id
23
+ end
24
+ end
17
25
  end
18
26
  end
19
- end
27
+ end
@@ -16,12 +16,16 @@ module ActiveRecord
16
16
  self.arel.visitor.accept(attribute)
17
17
  end.join(', ')
18
18
 
19
- relation = self.clone
20
- relation.select_values = ["DISTINCT #{projection}"]
19
+ # relation = self.clone
20
+ # relation.select_values = ["DISTINCT #{projection}"]
21
21
 
22
- table = Arel::Table.new('dummy').project('count(*)')
23
- relation = table.from(relation.arel, "foobar")
24
- type_cast_calculated_value(@klass.connection.select_value(relation.to_sql), column_for(column_name), operation)
22
+ manager = Arel::SelectManager.new(arel_engine)
23
+ manager.project("DISTINCT #{projection}")
24
+ manager.from(arel_table)
25
+
26
+ query = Arel::Table.new('dummy').project('count(*)')
27
+ query = query.from("(#{manager.to_sql}) AS subquery")
28
+ type_cast_calculated_value(@klass.connection.select_value(query.to_sql), column_for(column_name), operation)
25
29
  end
26
30
  end
27
31
  end
@@ -2,7 +2,7 @@ module CompositePrimaryKeys
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 3
4
4
  MINOR = 1
5
- TINY = 6
5
+ TINY = 7
6
6
  STRING = [MAJOR, MINOR, TINY].join('.')
7
7
  end
8
8
  end
@@ -7,16 +7,15 @@ require 'pp'
7
7
  require 'test/unit'
8
8
  require 'hash_tricks'
9
9
  require 'rubygems'
10
- require 'active_record'
11
- require 'active_record/fixtures'
12
- require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
13
- require File.join(PROJECT_ROOT, "test", "connections", "native_#{adapter}", "connection")
14
-
15
10
 
16
11
  # To make debugging easier, test within this source tree versus an installed gem
17
12
  #require 'composite_primary_keys'
18
13
  require File.join(PROJECT_ROOT, "lib", "composite_primary_keys")
19
14
 
15
+ require 'active_record/fixtures'
16
+ require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
17
+ require File.join(PROJECT_ROOT, "test", "connections", "native_#{adapter}", "connection")
18
+
20
19
  # Tell ActiveRecord where to find models
21
20
  ActiveSupport::Dependencies.autoload_paths << File.join(PROJECT_ROOT, 'test', 'fixtures')
22
21
 
@@ -7,7 +7,7 @@ def connection_string
7
7
  options['u'] = SPEC['username'] if SPEC['username']
8
8
  options['p'] = SPEC['password'] if SPEC['password']
9
9
  options['S'] = SPEC['sock'] if SPEC['sock']
10
- options.map { |key, value| "-#{key} #{value}" }.join(" ")
10
+ options.map { |key, value| "-#{key}#{value}" }.join(" ")
11
11
  end
12
12
 
13
13
  # Adapter config setup in locals/database_connections.rb
@@ -1,5 +1,4 @@
1
1
  class Department < ActiveRecord::Base
2
- # set_primary_keys *keys - turns on composite key functionality
3
2
  set_primary_keys :department_id, :location_id
4
3
  has_many :employees, :foreign_key => [:department_id, :location_id]
5
4
  end
@@ -1,3 +1,3 @@
1
1
  class Dorm < ActiveRecord::Base
2
- has_many :rooms, :include => :room_attributes
2
+ has_many :rooms, :include => :room_attributes, :primary_key => [:id]
3
3
  end
@@ -1,2 +1,2 @@
1
- jacksons_dorm:
1
+ branner:
2
2
  id: 1
@@ -1,7 +1,7 @@
1
1
  class Product < ActiveRecord::Base
2
2
  set_primary_keys :id # redundant
3
3
  has_many :product_tariffs, :foreign_key => :product_id, :dependent => :delete_all
4
- has_one :product_tariff, :foreign_key => :product_id
5
-
4
+ # Yeah, this is fake, it uses for testing
5
+ has_one :product_tariff, :foreign_key => :product_id
6
6
  has_many :tariffs, :through => :product_tariffs, :foreign_key => [:tariff_id, :tariff_start_date]
7
7
  end
@@ -2,10 +2,12 @@ first_flat:
2
2
  product_id: 1
3
3
  tariff_id: 1
4
4
  tariff_start_date: <%= Date.today.to_s(:db) %>
5
+
5
6
  first_free:
6
7
  product_id: 1
7
8
  tariff_id: 2
8
9
  tariff_start_date: <%= Date.today.to_s(:db) %>
10
+
9
11
  second_free:
10
12
  product_id: 2
11
13
  tariff_id: 2
@@ -1,6 +1,7 @@
1
1
  first_product:
2
2
  id: 1
3
3
  name: Product One
4
+
4
5
  second_product:
5
6
  id: 2
6
7
  name: Product Two
@@ -1,6 +1,7 @@
1
1
  class Room < ActiveRecord::Base
2
2
  set_primary_keys :dorm_id, :room_id
3
3
  belongs_to :dorm
4
+ has_many :room_assignments, :foreign_key => [:dorm_id, :room_id]
4
5
  has_many :room_attribute_assignments, :foreign_key => [:dorm_id, :room_id]
5
6
  has_many :room_attributes, :through => :room_attribute_assignments
6
7
 
@@ -1,6 +1,7 @@
1
1
  class RoomAssignment < ActiveRecord::Base
2
+ set_primary_keys :student_id, :dorm_id, :room_id
2
3
  belongs_to :student
3
- belongs_to :room, :foreign_key => [:dorm_id, :room_id]
4
+ belongs_to :room, :foreign_key => [:dorm_id, :room_id], :primary_key => [:dorm_id, :room_id]
4
5
 
5
6
  before_destroy do |record|
6
7
  puts record
@@ -1,4 +1,9 @@
1
1
  jacksons_room:
2
2
  student_id: 1
3
3
  dorm_id: 1
4
+ room_id: 1
5
+
6
+ bobs_room:
7
+ student_id: 2
8
+ dorm_id: 1
4
9
  room_id: 1
@@ -1,3 +1,7 @@
1
- jacksons_room:
2
- dorm_id: 1
3
- room_id: 1
1
+ branner_room_1:
2
+ dorm_id: 1
3
+ room_id: 1
4
+
5
+ branner_room_2:
6
+ dorm_id: 1
7
+ room_id: 2
@@ -1,2 +1,5 @@
1
1
  jackson:
2
- id: 1
2
+ id: 1
3
+
4
+ bob:
5
+ id: 2
@@ -5,26 +5,6 @@ class TestAssociations < ActiveSupport::TestCase
5
5
  :dorms, :rooms, :room_attributes, :room_attribute_assignments, :students, :room_assignments, :users, :readings,
6
6
  :memberships
7
7
 
8
- def test_has_many_through_with_conditions_when_through_association_is_not_composite
9
- user = User.find(:first)
10
- assert_equal 1, user.articles.find(:all, :conditions => ["articles.name = ?", "Article One"]).size
11
- end
12
-
13
- def test_has_many_through_with_conditions_when_through_association_is_composite
14
- room = Room.find(:first)
15
- assert_equal 0, room.room_attributes.find(:all, :conditions => ["room_attributes.name != ?", "keg"]).size
16
- end
17
-
18
- def test_has_many_through_on_custom_finder_when_through_association_is_composite_finder_when_through_association_is_not_composite
19
- user = User.find(:first)
20
- assert_equal 1, user.find_custom_articles.size
21
- end
22
-
23
- def test_has_many_through_on_custom_finder_when_through_association_is_composite
24
- room = Room.find(:first)
25
- assert_equal 0, room.find_custom_room_attributes.size
26
- end
27
-
28
8
  def test_count
29
9
  assert_equal(2, Product.count(:include => :product_tariffs))
30
10
  assert_equal(3, Tariff.count(:include => :product_tariffs))
@@ -141,9 +121,9 @@ class TestAssociations < ActiveSupport::TestCase
141
121
 
142
122
  def test_has_many_through_when_through_association_is_composite
143
123
  dorm = Dorm.find(:first)
144
- assert_equal 1, dorm.rooms.length
145
- assert_equal 1, dorm.rooms.first.room_attributes.length
146
- assert_equal 'keg', dorm.rooms.first.room_attributes.first.name
124
+ assert_equal(2, dorm.rooms.length)
125
+ assert_equal(1, dorm.rooms.first.room_attributes.length)
126
+ assert_equal('keg', dorm.rooms.first.room_attributes.first.name)
147
127
  end
148
128
 
149
129
  def test_associations_with_conditions
@@ -160,6 +140,18 @@ class TestAssociations < ActiveSupport::TestCase
160
140
  assert_equal 1, @suburb.first_streets.size
161
141
  end
162
142
 
143
+ def test_composite_has_many_composites
144
+ room = rooms(:branner_room_1)
145
+ assert_equal(2, room.room_assignments.length)
146
+ assert_equal(room_assignments(:jacksons_room), room.room_assignments[0])
147
+ assert_equal(room_assignments(:bobs_room), room.room_assignments[1])
148
+ end
149
+
150
+ def test_composite_belongs_to_composite
151
+ room_assignment = room_assignments(:jacksons_room)
152
+ assert_equal(rooms(:branner_room_1), room_assignment.room)
153
+ end
154
+
163
155
  def test_has_and_belongs_to_many
164
156
  @restaurant = Restaurant.find([1,1])
165
157
  assert_equal 2, @restaurant.suburbs.size
@@ -168,16 +160,29 @@ class TestAssociations < ActiveSupport::TestCase
168
160
  assert_equal 2, @restaurant.suburbs.size
169
161
  end
170
162
 
171
- def test_has_many_with_primary_key
163
+ def test_has_one_with_primary_key
172
164
  @membership = Membership.find([1, 1])
165
+ assert_equal 2, @membership.reading.id
166
+ end
173
167
 
174
- assert_equal 2, @membership.readings.size
168
+ def test_has_one_with_composite
169
+ # In this case a regular model has_one composite model
170
+ product = products(:first_product)
171
+ assert_not_nil(product.product_tariff)
175
172
  end
176
173
 
177
- def test_has_one_with_primary_key
174
+ def test_has_many_with_primary_key
178
175
  @membership = Membership.find([1, 1])
179
176
 
180
- assert_equal 2, @membership.reading.id
177
+ assert_equal 2, @membership.readings.size
178
+ end
179
+
180
+ def test_has_many_with_composite_key
181
+ # In this case a regular model has_many composite models
182
+ dorm = dorms(:branner)
183
+ assert_equal(2, dorm.rooms.length)
184
+ assert_equal(1, dorm.rooms[0].room_id)
185
+ assert_equal(2, dorm.rooms[1].room_id)
181
186
  end
182
187
 
183
188
  def test_joins_has_many_with_primary_key
@@ -192,6 +197,26 @@ class TestAssociations < ActiveSupport::TestCase
192
197
  assert_equal [1, 1], @membership.id
193
198
  end
194
199
 
200
+ def test_has_many_through_with_conditions_when_through_association_is_not_composite
201
+ user = User.find(:first)
202
+ assert_equal 1, user.articles.find(:all, :conditions => ["articles.name = ?", "Article One"]).size
203
+ end
204
+
205
+ def test_has_many_through_with_conditions_when_through_association_is_composite
206
+ room = Room.find(:first)
207
+ assert_equal 0, room.room_attributes.find(:all, :conditions => ["room_attributes.name != ?", "keg"]).size
208
+ end
209
+
210
+ def test_has_many_through_on_custom_finder_when_through_association_is_composite_finder_when_through_association_is_not_composite
211
+ user = User.find(:first)
212
+ assert_equal 1, user.find_custom_articles.size
213
+ end
214
+
215
+ def test_has_many_through_on_custom_finder_when_through_association_is_composite
216
+ room = Room.find(:first)
217
+ assert_equal 0, room.find_custom_room_attributes.size
218
+ end
219
+
195
220
  def test_has_many_with_primary_key_with_associations
196
221
  # Trigger Active Records find_with_associations method
197
222
  memberships = Membership.find(:all, :include => :statuses,
data/test/test_create.rb CHANGED
@@ -38,7 +38,7 @@ class TestCreate < ActiveSupport::TestCase
38
38
  begin
39
39
  @obj = @klass.create(@klass_info[:create].block(@klass.primary_key))
40
40
  @successful = !composite?
41
- rescue CompositePrimaryKeys::ActiveRecord::CompositeKeyError
41
+ rescue ActiveRecord::CompositeKeyError
42
42
  @successful = false
43
43
  rescue
44
44
  flunk "Incorrect exception raised: #{$!}, #{$!.class}"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: composite_primary_keys
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 13
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 1
9
- - 6
10
- version: 3.1.6
9
+ - 7
10
+ version: 3.1.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dr Nic Williams
@@ -16,13 +16,28 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-04-03 00:00:00 -06:00
20
- default_executable:
19
+ date: 2011-05-19 00:00:00 Z
21
20
  dependencies:
22
21
  - !ruby/object:Gem::Dependency
23
- name: activerecord
22
+ name: arel
24
23
  prerelease: false
25
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 15
30
+ segments:
31
+ - 2
32
+ - 0
33
+ - 0
34
+ version: 2.0.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: activerecord
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
26
41
  none: false
27
42
  requirements:
28
43
  - - ">="
@@ -33,12 +48,20 @@ dependencies:
33
48
  - 0
34
49
  - 5
35
50
  version: 3.0.5
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ hash: 7
54
+ segments:
55
+ - 3
56
+ - 0
57
+ - 0
58
+ version: 3.0.0
36
59
  type: :runtime
37
- version_requirements: *id001
60
+ version_requirements: *id002
38
61
  - !ruby/object:Gem::Dependency
39
62
  name: rspec
40
63
  prerelease: false
41
- requirement: &id002 !ruby/object:Gem::Requirement
64
+ requirement: &id003 !ruby/object:Gem::Requirement
42
65
  none: false
43
66
  requirements:
44
67
  - - ">="
@@ -48,7 +71,7 @@ dependencies:
48
71
  - 0
49
72
  version: "0"
50
73
  type: :development
51
- version_requirements: *id002
74
+ version_requirements: *id003
52
75
  description: Composite key support for ActiveRecord 3
53
76
  email:
54
77
  - drnicwilliams@gmail.com
@@ -66,7 +89,6 @@ files:
66
89
  - init.rb
67
90
  - install.rb
68
91
  - loader.rb
69
- - lib/composite_primary_keys/arel_extensions.rb
70
92
  - lib/composite_primary_keys/associations/association_proxy.rb
71
93
  - lib/composite_primary_keys/associations/has_and_belongs_to_many_association.rb
72
94
  - lib/composite_primary_keys/associations/has_many_association.rb
@@ -186,7 +208,6 @@ files:
186
208
  - test/plugins/pagination_helper.rb
187
209
  - test/README_tests.txt
188
210
  - test/setup.rb
189
- - test/test_arel.rb
190
211
  - test/test_associations.rb
191
212
  - test/test_attributes.rb
192
213
  - test/test_attribute_methods.rb
@@ -206,7 +227,6 @@ files:
206
227
  - test/test_tutorial_example.rb
207
228
  - test/test_update.rb
208
229
  - test/test_validations.rb
209
- has_rdoc: true
210
230
  homepage: http://github.com/cfis/composite_primary_keys
211
231
  licenses: []
212
232
 
@@ -238,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
238
258
  requirements: []
239
259
 
240
260
  rubyforge_project: compositekeys
241
- rubygems_version: 1.6.2
261
+ rubygems_version: 1.7.2
242
262
  signing_key:
243
263
  specification_version: 3
244
264
  summary: Composite key support for ActiveRecord
@@ -249,7 +269,6 @@ test_files:
249
269
  - test/hash_tricks.rb
250
270
  - test/README_tests.txt
251
271
  - test/setup.rb
252
- - test/test_arel.rb
253
272
  - test/test_associations.rb
254
273
  - test/test_attributes.rb
255
274
  - test/test_attribute_methods.rb
@@ -1,47 +0,0 @@
1
- module Arel
2
- module Nodes
3
- class SubSelect < Node
4
- attr_accessor :select, :as
5
-
6
- def initialize(select, as = 'subquery')
7
- @select = select
8
- @as = as
9
- end
10
- end
11
- end
12
-
13
- module Visitors
14
- class ToSql
15
- def visit_Arel_Nodes_SubSelect o
16
- "(#{visit(o.select)}) AS #{o.as}"
17
- end
18
- end
19
- end
20
-
21
- class SelectManager
22
- def from table, as = nil
23
- table = case table
24
- when Arel::SelectManager
25
- Nodes::SubSelect.new(table.ast, as)
26
- when String
27
- Nodes::SqlLiteral.new(table)
28
- else
29
- table
30
- end
31
-
32
- # FIXME: this is a hack to support
33
- # test_with_two_tables_in_from_without_getting_double_quoted
34
- # from the AR tests.
35
- if @ctx.froms
36
- source = @ctx.froms
37
-
38
- if Nodes::SqlLiteral === table && Nodes::Join === source
39
- source.left = table
40
- table = source
41
- end
42
- end
43
- @ctx.froms = table
44
- self
45
- end
46
- end
47
- end
data/test/test_arel.rb DELETED
@@ -1,79 +0,0 @@
1
- require 'abstract_unit'
2
-
3
-
4
- module Arel
5
- module Nodes
6
- class SubSelect < Node
7
- attr_accessor :select, :as
8
-
9
- def initialize(select, as = 'subquery')
10
- @select = select
11
- @as = as
12
- end
13
- end
14
- end
15
-
16
- module Visitors
17
- class ToSql
18
- def visit_Arel_Nodes_SubSelect o
19
- "(#{visit(o.select)}) AS #{o.as}"
20
- end
21
- end
22
- end
23
-
24
- class SelectManager
25
- def from table, as = nil
26
- table = case table
27
- when Arel::SelectManager
28
- Nodes::SubSelect.new(table.ast, as)
29
- when String
30
- Nodes::SqlLiteral.new(table)
31
- else
32
- table
33
- end
34
-
35
- # FIXME: this is a hack to support
36
- # test_with_two_tables_in_from_without_getting_double_quoted
37
- # from the AR tests.
38
- if @ctx.froms
39
- source = @ctx.froms
40
-
41
- if Nodes::SqlLiteral === table && Nodes::Join === source
42
- source.left = table
43
- table = source
44
- end
45
- end
46
- @ctx.froms = table
47
- self
48
- end
49
- end
50
- end
51
-
52
-
53
-
54
- #class TestArel < Test::Unit::TestCase
55
- # def test_engine
56
- # assert_not_nil(Arel::Table)
57
- # assert_not_nil(Arel::Table.engine)
58
- # end
59
- #end
60
-
61
- visitor = Arel::Visitors::ToSql.new(Arel::Table.engine)
62
-
63
- tariffs = Arel::Table.new(:tariffs)
64
- product_tariffs = Arel::Table.new(:product_tariffs)
65
- subquery = tariffs.join(product_tariffs).on(tariffs[:tariff_id].eq(product_tariffs[:tariff_id]).and(tariffs[:start_date].eq(product_tariffs[:tariff_start_date])))
66
-
67
- projection = ['tariff_id', 'start_date'].map do |key|
68
- visitor.accept(tariffs[key])
69
- end.join(', ')
70
-
71
- subquery.project("DISTINCT #{projection}")
72
-
73
- table = Arel::Table.new('test').project('count(*)')
74
- query = table.from(subquery, "foobar")
75
-
76
- puts "***********"
77
- puts query.to_sql
78
- a = query.to_a
79
- puts a