composite_primary_keys 8.1.2 → 8.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.rdoc +8 -0
- data/lib/composite_primary_keys.rb +3 -0
- data/lib/composite_primary_keys/arel/visitors/to_sql.rb +13 -1
- data/lib/composite_primary_keys/associations/has_many_through_association.rb +2 -1
- data/lib/composite_primary_keys/autosave_association.rb +31 -0
- data/lib/composite_primary_keys/connection_adapters/abstract_mysql_adapter.rb +23 -0
- data/lib/composite_primary_keys/version.rb +1 -1
- data/test/fixtures/user.rb +11 -10
- data/test/test_associations.rb +10 -0
- data/test/test_delete_all.rb +3 -2
- data/test/test_polymorphic.rb +7 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5dcd8c948f14181d3e5ebb97a5a79f124e7e9cef
|
4
|
+
data.tar.gz: 435b1a7ffaf2c481b09b268fd28585112a092f44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c38c11665ea24815069cd8c2c14701108cc1516663cba835eb044db3ebcabc26d46dee9db88d9c2c6923d992ee3c0b8293825ca3f2af88411641a1ed0a4bff67
|
7
|
+
data.tar.gz: cd22418296a7ffbd27c5ece78c7bc835be47bd50b4a4ed51c96bea564225fa3ebc9782fb60ba6b02a76d7784074c56c2df82d7d3e443cd7e17053ab8a25b43f9
|
data/History.rdoc
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 8.1.3 (2016-04-16)
|
2
|
+
|
3
|
+
* Make CPK work for Arel::Attributes::Attribute (Rick Xing)
|
4
|
+
* Change autosave_association.rb so that association autosave can work (Rick Xing)
|
5
|
+
* Fix exception when saving "other_ids=" with a has_many :through association where the source
|
6
|
+
association is polymorphic (Tye Shavik)
|
7
|
+
* Fix Arel::Nodes::In where left side is not a column (Tye Shavik)
|
8
|
+
|
1
9
|
== 8.1.2 (2015-12-13)
|
2
10
|
|
3
11
|
* Fix failing tests
|
@@ -61,6 +61,7 @@ require 'active_record/locking/optimistic'
|
|
61
61
|
require 'active_record/nested_attributes'
|
62
62
|
|
63
63
|
require 'active_record/connection_adapters/abstract_adapter'
|
64
|
+
require 'active_record/connection_adapters/abstract_mysql_adapter'
|
64
65
|
|
65
66
|
require 'active_record/relation/batches'
|
66
67
|
require 'active_record/relation/calculations'
|
@@ -97,6 +98,7 @@ require 'composite_primary_keys/associations/singular_association'
|
|
97
98
|
require 'composite_primary_keys/associations/collection_association'
|
98
99
|
|
99
100
|
require 'composite_primary_keys/dirty'
|
101
|
+
require 'composite_primary_keys/autosave_association'
|
100
102
|
|
101
103
|
require 'composite_primary_keys/attribute_methods/primary_key'
|
102
104
|
require 'composite_primary_keys/attribute_methods/dirty'
|
@@ -106,6 +108,7 @@ require 'composite_primary_keys/locking/optimistic'
|
|
106
108
|
require 'composite_primary_keys/nested_attributes'
|
107
109
|
|
108
110
|
require 'composite_primary_keys/connection_adapters/abstract_adapter'
|
111
|
+
require 'composite_primary_keys/connection_adapters/abstract_mysql_adapter'
|
109
112
|
require 'composite_primary_keys/connection_adapters/abstract/connection_specification_changes'
|
110
113
|
|
111
114
|
require 'composite_primary_keys/relation/batches'
|
@@ -1,13 +1,25 @@
|
|
1
1
|
module Arel
|
2
2
|
module Visitors
|
3
3
|
class ToSql
|
4
|
+
def visit_Arel_Attributes_Attribute o, collector
|
5
|
+
join_name = o.relation.table_alias || o.relation.name
|
6
|
+
table_name = quote_table_name join_name
|
7
|
+
|
8
|
+
if o.name.is_a? Array
|
9
|
+
collector <<
|
10
|
+
o.name.map{ |field| "#{table_name}.#{quote_column_name(field)}" }.join(",")
|
11
|
+
else
|
12
|
+
collector << "#{table_name}.#{quote_column_name o.name}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
4
16
|
def visit_Arel_Nodes_In o, collector
|
5
17
|
if Array === o.right && o.right.empty?
|
6
18
|
collector << '1=0'
|
7
19
|
else
|
8
20
|
# CPK
|
9
21
|
# collector = visit o.left, collector
|
10
|
-
if o.left.name.is_a?(Array)
|
22
|
+
if o.left.respond_to?(:name) && o.left.name.is_a?(Array)
|
11
23
|
collector << "("
|
12
24
|
collector = visit(o.left, collector)
|
13
25
|
collector << ")"
|
@@ -19,7 +19,8 @@ module ActiveRecord
|
|
19
19
|
scope = through_association.scope
|
20
20
|
# CPK
|
21
21
|
# scope.where! construct_join_attributes(*records)
|
22
|
-
|
22
|
+
source_klass = source_reflection.polymorphic? ? klass : source_reflection.klass
|
23
|
+
if source_klass.composite?
|
23
24
|
scope.where! cpk_join_through_predicate(*records)
|
24
25
|
else
|
25
26
|
scope.where! construct_join_attributes(*records)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module AutosaveAssociation
|
3
|
+
private
|
4
|
+
# Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
|
5
|
+
#
|
6
|
+
# In addition, it will destroy the association if it was marked for destruction.
|
7
|
+
def save_belongs_to_association(reflection)
|
8
|
+
association = association_instance_get(reflection.name)
|
9
|
+
record = association && association.load_target
|
10
|
+
if record && !record.destroyed?
|
11
|
+
autosave = reflection.options[:autosave]
|
12
|
+
|
13
|
+
if autosave && record.marked_for_destruction?
|
14
|
+
self[reflection.foreign_key] = nil
|
15
|
+
record.destroy
|
16
|
+
elsif autosave != false
|
17
|
+
saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
|
18
|
+
|
19
|
+
if association.updated?
|
20
|
+
# it will fail to use "#record.send(reflection.options[:primary_key] || :id)" for CPK
|
21
|
+
association_id = record.read_attribute(reflection.options[:primary_key] || :id)
|
22
|
+
self[reflection.foreign_key] = association_id
|
23
|
+
association.loaded!
|
24
|
+
end
|
25
|
+
|
26
|
+
saved if autosave
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
class AbstractMysqlAdapter < AbstractAdapter
|
4
|
+
# MySQL is too stupid to create a temporary table for use subquery, so we have
|
5
|
+
# to give it some prompting in the form of a subsubquery. Ugh!
|
6
|
+
def subquery_for(key, select)
|
7
|
+
subsubselect = select.clone
|
8
|
+
subsubselect.projections = [key]
|
9
|
+
|
10
|
+
# Materialize subquery by adding distinct
|
11
|
+
# to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on'
|
12
|
+
subsubselect.distinct unless select.limit || select.offset || select.orders.any?
|
13
|
+
|
14
|
+
subselect = Arel::SelectManager.new(select.engine)
|
15
|
+
|
16
|
+
# subselect.project Arel.sql(key.name)
|
17
|
+
arel_table = select.engine.arel_table
|
18
|
+
subselect.project *key.name.map{|x| arel_table[x]}
|
19
|
+
subselect.from subsubselect.as('__active_record_temp')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/test/fixtures/user.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
class User < ActiveRecord::Base
|
2
|
-
has_many :readings
|
3
|
-
has_many :articles, :through => :readings
|
4
|
-
has_many :comments, :as => :person
|
5
|
-
has_many :hacks, :through => :comments, :source => :hack
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
has_many :readings
|
3
|
+
has_many :articles, :through => :readings
|
4
|
+
has_many :comments, :as => :person
|
5
|
+
has_many :hacks, :through => :comments, :source => :hack
|
6
|
+
has_many :persons, :through => :comments, :source_type => 'User'
|
7
|
+
|
8
|
+
def find_custom_articles
|
9
|
+
articles.where("name = ?", "Article One")
|
10
|
+
end
|
11
|
+
end
|
data/test/test_associations.rb
CHANGED
@@ -81,6 +81,16 @@ class TestAssociations < ActiveSupport::TestCase
|
|
81
81
|
refute_equal accounting_head, engineering_head
|
82
82
|
end
|
83
83
|
|
84
|
+
def test_association_with_composite_primary_key_can_be_autosaved
|
85
|
+
room = Room.new(dorm_id: 1000, room_id: 1001)
|
86
|
+
room_assignment = RoomAssignment.new(student_id: 1000)
|
87
|
+
room_assignment.room = room
|
88
|
+
room_assignment.save
|
89
|
+
room_assignment.reload
|
90
|
+
assert_equal(room_assignment.dorm_id, 1000)
|
91
|
+
assert_equal(room_assignment.room_id, 1001)
|
92
|
+
end
|
93
|
+
|
84
94
|
def test_has_one_association_primary_key_and_foreign_key_are_present
|
85
95
|
steve = employees(:steve)
|
86
96
|
steve_salary = steve.create_one_salary(year: "2015", month: "1")
|
data/test/test_delete_all.rb
CHANGED
@@ -27,8 +27,9 @@ class TestValidations < ActiveSupport::TestCase
|
|
27
27
|
assert(EmployeesGroup.all.size == 3)
|
28
28
|
end
|
29
29
|
|
30
|
-
# This test fails, requires fixin arel
|
31
30
|
def test_delete_all_with_joins
|
32
|
-
|
31
|
+
# Let's ignore SQLite for this case since multi-column IN clause like (column1, column2) IN (...) is not allowed.
|
32
|
+
# It cannot work without some dirty fix.
|
33
|
+
ReferenceCode.joins(:reference_type).where(:reference_type_id => 1).delete_all unless ReferenceCode.connection.adapter_name == "SQLite"
|
33
34
|
end
|
34
35
|
end
|
data/test/test_polymorphic.rb
CHANGED
@@ -24,4 +24,11 @@ class TestPolymorphic < ActiveSupport::TestCase
|
|
24
24
|
user = users(:santiago)
|
25
25
|
assert_equal(['andrew'], user.hacks.collect { |a| a.name }.sort)
|
26
26
|
end
|
27
|
+
|
28
|
+
def test_has_many_through_with_polymorphic_source
|
29
|
+
user = users(:santiago)
|
30
|
+
user_to_associate = users(:drnic)
|
31
|
+
user.update_attributes :persons => [user_to_associate]
|
32
|
+
assert_equal user.persons, [user_to_associate]
|
33
|
+
end
|
27
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: composite_primary_keys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.1.
|
4
|
+
version: 8.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charlie Savage
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -94,12 +94,14 @@ files:
|
|
94
94
|
- lib/composite_primary_keys/attribute_methods/read.rb
|
95
95
|
- lib/composite_primary_keys/attribute_methods/write.rb
|
96
96
|
- lib/composite_primary_keys/attribute_set/builder.rb
|
97
|
+
- lib/composite_primary_keys/autosave_association.rb
|
97
98
|
- lib/composite_primary_keys/base.rb
|
98
99
|
- lib/composite_primary_keys/composite_arrays.rb
|
99
100
|
- lib/composite_primary_keys/composite_predicates.rb
|
100
101
|
- lib/composite_primary_keys/composite_relation.rb
|
101
102
|
- lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb
|
102
103
|
- lib/composite_primary_keys/connection_adapters/abstract_adapter.rb
|
104
|
+
- lib/composite_primary_keys/connection_adapters/abstract_mysql_adapter.rb
|
103
105
|
- lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb
|
104
106
|
- lib/composite_primary_keys/connection_adapters/sqlserver_adapter.rb
|
105
107
|
- lib/composite_primary_keys/core.rb
|
@@ -266,7 +268,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
266
268
|
version: '0'
|
267
269
|
requirements: []
|
268
270
|
rubyforge_project:
|
269
|
-
rubygems_version: 2.
|
271
|
+
rubygems_version: 2.5.1
|
270
272
|
signing_key:
|
271
273
|
specification_version: 4
|
272
274
|
summary: Composite key support for ActiveRecord
|