store_base_sti_class 2.0.1 → 2.0.2
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.
- checksums.yaml +4 -4
- data/Appraisals +4 -4
- data/Gemfile.lock +20 -21
- data/README.md +17 -1
- data/gemfiles/{rails_5.1.6.gemfile → rails_5.1.7.gemfile} +1 -1
- data/gemfiles/{rails_6.0.1.gemfile → rails_6.0.3.gemfile} +1 -1
- data/gemfiles/{rails_4.2.11.gemfile → rails_6.1.0.gemfile} +2 -2
- data/lib/store_base_sti_class.rb +3 -3
- data/lib/store_base_sti_class/version.rb +1 -1
- data/lib/store_base_sti_class_for_6_1.rb +156 -0
- metadata +10 -10
- data/lib/store_base_sti_class_for_4_2.rb +0 -360
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 59deb36c4e242478eb3aea835560dd54845a59120e798e7c3d2945609da51fc7
|
|
4
|
+
data.tar.gz: c2320ddcb07a37711a13dfe9d700da253c419f85a9aebec37a7c33c468fa0ac4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 03e0e8037ed8d2642e239be605ea68e7fdd808c94e76741767c2d822b3045b814c04e24dff970188fd9a283e735eda67cd4f5334b347b9dab1f3d02fbd5fa957
|
|
7
|
+
data.tar.gz: 8314c4ff6de5199bdad4605ef5a042cdec5935f0e3102ed99637dd7e5d90c4616d8571eec34e64da758207e14834eb98ef05a3aa99503e8efbac3f408dc2af6c
|
data/Appraisals
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
RAILS_VERSIONS = %w[
|
|
2
|
-
4.2.11
|
|
3
2
|
5.0.7
|
|
4
|
-
5.1.
|
|
3
|
+
5.1.7
|
|
5
4
|
5.2.3
|
|
6
5
|
5.2.4
|
|
7
|
-
6.0.
|
|
6
|
+
6.0.3
|
|
7
|
+
6.1.0
|
|
8
8
|
].freeze
|
|
9
9
|
|
|
10
10
|
RAILS_VERSIONS.each do |version|
|
|
11
11
|
appraise "rails_#{version}" do
|
|
12
12
|
gem 'activerecord', version
|
|
13
|
-
gem 'sqlite3',
|
|
13
|
+
gem 'sqlite3', ['6.0.3', '6.1.0'].include?(version) ? '~> 1.4.0' : '~> 1.3.0'
|
|
14
14
|
end
|
|
15
15
|
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,37 +1,36 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
store_base_sti_class (2.0.
|
|
4
|
+
store_base_sti_class (2.0.2)
|
|
5
5
|
activerecord (>= 4.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
activemodel (6.0
|
|
11
|
-
activesupport (= 6.0
|
|
12
|
-
activerecord (6.0
|
|
13
|
-
activemodel (= 6.0
|
|
14
|
-
activesupport (= 6.0
|
|
15
|
-
activesupport (6.0
|
|
10
|
+
activemodel (6.1.0)
|
|
11
|
+
activesupport (= 6.1.0)
|
|
12
|
+
activerecord (6.1.0)
|
|
13
|
+
activemodel (= 6.1.0)
|
|
14
|
+
activesupport (= 6.1.0)
|
|
15
|
+
activesupport (6.1.0)
|
|
16
16
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
17
|
-
i18n (>=
|
|
18
|
-
minitest (
|
|
19
|
-
tzinfo (~>
|
|
20
|
-
zeitwerk (~> 2.
|
|
21
|
-
appraisal (2.
|
|
17
|
+
i18n (>= 1.6, < 2)
|
|
18
|
+
minitest (>= 5.1)
|
|
19
|
+
tzinfo (~> 2.0)
|
|
20
|
+
zeitwerk (~> 2.3)
|
|
21
|
+
appraisal (2.3.0)
|
|
22
22
|
bundler
|
|
23
23
|
rake
|
|
24
24
|
thor (>= 0.14.0)
|
|
25
|
-
concurrent-ruby (1.1.
|
|
26
|
-
i18n (1.
|
|
25
|
+
concurrent-ruby (1.1.7)
|
|
26
|
+
i18n (1.8.5)
|
|
27
27
|
concurrent-ruby (~> 1.0)
|
|
28
|
-
minitest (5.
|
|
28
|
+
minitest (5.14.2)
|
|
29
29
|
rake (13.0.1)
|
|
30
|
-
thor (0.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
zeitwerk (2.2.1)
|
|
30
|
+
thor (1.0.1)
|
|
31
|
+
tzinfo (2.0.3)
|
|
32
|
+
concurrent-ruby (~> 1.0)
|
|
33
|
+
zeitwerk (2.4.2)
|
|
35
34
|
|
|
36
35
|
PLATFORMS
|
|
37
36
|
ruby
|
|
@@ -43,4 +42,4 @@ DEPENDENCIES
|
|
|
43
42
|
store_base_sti_class!
|
|
44
43
|
|
|
45
44
|
BUNDLED WITH
|
|
46
|
-
1.
|
|
45
|
+
2.1.4
|
data/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
[](https://github.com/appfolio/store_base_sti_class/actions)
|
|
2
|
+
|
|
2
3
|
## Description
|
|
3
4
|
|
|
4
5
|
Given the following class definitions:
|
|
@@ -79,6 +80,21 @@ It currently works with ActiveRecord 4.2.x through 6.0.x. If you need support
|
|
|
79
80
|
for ActiveRecord 3.x, use a pre-1.0 version of the gem, or ActiveRecord < 4.2
|
|
80
81
|
use a pre-2.0 version of the gem.
|
|
81
82
|
|
|
83
|
+
## Conflicts
|
|
84
|
+
|
|
85
|
+
This gem produces known conflicts with these other gems:
|
|
86
|
+
|
|
87
|
+
### friendly_id
|
|
88
|
+
|
|
89
|
+
When using [friendly_id](https://github.com/norman/friendly_id) >= 5.2.5 with the [History module](https://norman.github.io/friendly_id/FriendlyId/History.html) enabled, duplicate slugs will be generated for STI subclasses with the same sluggable identifier (ex: name). This will either cause saves to fail if you have the proper indexes in place, or will cause slug lookups to be non-deterministic, either of which is undesirable.
|
|
90
|
+
|
|
91
|
+
## History
|
|
92
|
+
|
|
93
|
+
* https://github.com/rails/rails/issues/724
|
|
94
|
+
* https://github.com/rails/rails/issues/5441#issuecomment-4563865
|
|
95
|
+
* https://github.com/rails/rails/issues/4729#issuecomment-5729297
|
|
96
|
+
* https://github.com/rails/rails/issues/5441#issuecomment-264871920
|
|
97
|
+
|
|
82
98
|
## Copyright
|
|
83
99
|
|
|
84
100
|
Copyright (c) 2011-2019 AppFolio, inc. See LICENSE.txt for
|
data/lib/store_base_sti_class.rb
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
require 'active_record'
|
|
2
2
|
|
|
3
|
-
if ActiveRecord::VERSION::STRING =~ /^
|
|
4
|
-
require 'store_base_sti_class_for_4_2'
|
|
5
|
-
elsif ActiveRecord::VERSION::STRING =~ /^5\.0/
|
|
3
|
+
if ActiveRecord::VERSION::STRING =~ /^5\.0/
|
|
6
4
|
require 'store_base_sti_class_for_5_0'
|
|
7
5
|
elsif ActiveRecord::VERSION::STRING =~ /^5\.1/
|
|
8
6
|
require 'store_base_sti_class_for_5_1'
|
|
@@ -10,6 +8,8 @@ elsif ActiveRecord::VERSION::STRING =~ /^5\.2/
|
|
|
10
8
|
require 'store_base_sti_class_for_5_2'
|
|
11
9
|
elsif ActiveRecord::VERSION::STRING =~ /^6\.0/
|
|
12
10
|
require 'store_base_sti_class_for_6_0'
|
|
11
|
+
elsif ActiveRecord::VERSION::STRING =~ /^6\.1/
|
|
12
|
+
require 'store_base_sti_class_for_6_1'
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
module StoreBaseSTIClass
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
require 'active_record/associations/join_dependency/join_part'
|
|
2
|
+
|
|
3
|
+
if ActiveRecord::VERSION::STRING =~ /^6\.1/
|
|
4
|
+
module ActiveRecord
|
|
5
|
+
|
|
6
|
+
class Base
|
|
7
|
+
class_attribute :store_base_sti_class
|
|
8
|
+
self.store_base_sti_class = true
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module Inheritance
|
|
12
|
+
module ClassMethods
|
|
13
|
+
def polymorphic_name
|
|
14
|
+
ActiveRecord::Base.store_base_sti_class ? base_class.name : name
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module Associations
|
|
20
|
+
class Preloader
|
|
21
|
+
class ThroughAssociation < Association
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def through_scope
|
|
25
|
+
scope = through_reflection.klass.unscoped
|
|
26
|
+
options = reflection.options
|
|
27
|
+
|
|
28
|
+
values = reflection_scope.values
|
|
29
|
+
if annotations = values[:annotate]
|
|
30
|
+
scope.annotate!(*annotations)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if options[:source_type]
|
|
34
|
+
# BEGIN PATCH
|
|
35
|
+
# original:
|
|
36
|
+
# scope.where! reflection.foreign_type => options[:source_type]
|
|
37
|
+
|
|
38
|
+
adjusted_foreign_type =
|
|
39
|
+
if ActiveRecord::Base.store_base_sti_class
|
|
40
|
+
options[:source_type]
|
|
41
|
+
else
|
|
42
|
+
([options[:source_type].constantize] + options[:source_type].constantize.descendants).map(&:to_s)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
scope.where! reflection.foreign_type => adjusted_foreign_type
|
|
46
|
+
# END PATCH
|
|
47
|
+
|
|
48
|
+
elsif !reflection_scope.where_clause.empty?
|
|
49
|
+
scope.where_clause = reflection_scope.where_clause
|
|
50
|
+
|
|
51
|
+
if includes = values[:includes]
|
|
52
|
+
scope.includes!(source_reflection.name => includes)
|
|
53
|
+
else
|
|
54
|
+
scope.includes!(source_reflection.name)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
if values[:references] && !values[:references].empty?
|
|
58
|
+
scope.references_values |= values[:references]
|
|
59
|
+
else
|
|
60
|
+
scope.references!(source_reflection.table_name)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
if joins = values[:joins]
|
|
64
|
+
scope.joins!(source_reflection.name => joins)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
if left_outer_joins = values[:left_outer_joins]
|
|
68
|
+
scope.left_outer_joins!(source_reflection.name => left_outer_joins)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if scope.eager_loading? && order_values = values[:order]
|
|
72
|
+
scope = scope.order(order_values)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
scope
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
class AssociationScope
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def next_chain_scope(scope, reflection, next_reflection)
|
|
85
|
+
primary_key = reflection.join_primary_key
|
|
86
|
+
foreign_key = reflection.join_foreign_key
|
|
87
|
+
|
|
88
|
+
table = reflection.aliased_table
|
|
89
|
+
foreign_table = next_reflection.aliased_table
|
|
90
|
+
constraint = table[primary_key].eq(foreign_table[foreign_key])
|
|
91
|
+
|
|
92
|
+
if reflection.type
|
|
93
|
+
# BEGIN PATCH
|
|
94
|
+
# original:
|
|
95
|
+
# value = transform_value(next_reflection.klass.polymorphic_name)
|
|
96
|
+
# scope = apply_scope(scope, table, reflection.type, value)
|
|
97
|
+
|
|
98
|
+
if ActiveRecord::Base.store_base_sti_class
|
|
99
|
+
value = transform_value(next_reflection.klass.polymorphic_name)
|
|
100
|
+
else
|
|
101
|
+
klass = next_reflection.klass
|
|
102
|
+
value = ([klass] + klass.descendants).map(&:name)
|
|
103
|
+
end
|
|
104
|
+
scope = apply_scope(scope, table, reflection.type, value)
|
|
105
|
+
# END PATCH
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
scope.joins!(join(foreign_table, constraint))
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
class HasManyThroughAssociation
|
|
114
|
+
private
|
|
115
|
+
|
|
116
|
+
def build_through_record(record)
|
|
117
|
+
@through_records[record.object_id] ||= begin
|
|
118
|
+
ensure_mutable
|
|
119
|
+
|
|
120
|
+
attributes = through_scope_attributes
|
|
121
|
+
attributes[source_reflection.name] = record
|
|
122
|
+
|
|
123
|
+
# START PATCH
|
|
124
|
+
if ActiveRecord::Base.store_base_sti_class
|
|
125
|
+
attributes[source_reflection.foreign_type] = options[:source_type] if options[:source_type]
|
|
126
|
+
end
|
|
127
|
+
# END PATCH
|
|
128
|
+
|
|
129
|
+
through_association.build(attributes)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
module Reflection
|
|
136
|
+
class PolymorphicReflection
|
|
137
|
+
def source_type_scope
|
|
138
|
+
type = @previous_reflection.foreign_type
|
|
139
|
+
source_type = @previous_reflection.options[:source_type]
|
|
140
|
+
|
|
141
|
+
# START PATCH
|
|
142
|
+
adjusted_source_type =
|
|
143
|
+
if ActiveRecord::Base.store_base_sti_class
|
|
144
|
+
source_type
|
|
145
|
+
else
|
|
146
|
+
([source_type.constantize] + source_type.constantize.descendants).map(&:to_s)
|
|
147
|
+
end
|
|
148
|
+
# END PATCH
|
|
149
|
+
|
|
150
|
+
lambda { |object| where(type => adjusted_source_type) }
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: store_base_sti_class
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- AppFolio
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-12-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -84,25 +84,25 @@ files:
|
|
|
84
84
|
- LICENSE.txt
|
|
85
85
|
- README.md
|
|
86
86
|
- Rakefile
|
|
87
|
-
- gemfiles/rails_4.2.11.gemfile
|
|
88
87
|
- gemfiles/rails_5.0.7.gemfile
|
|
89
|
-
- gemfiles/rails_5.1.
|
|
88
|
+
- gemfiles/rails_5.1.7.gemfile
|
|
90
89
|
- gemfiles/rails_5.2.3.gemfile
|
|
91
90
|
- gemfiles/rails_5.2.4.gemfile
|
|
92
|
-
- gemfiles/rails_6.0.
|
|
91
|
+
- gemfiles/rails_6.0.3.gemfile
|
|
92
|
+
- gemfiles/rails_6.1.0.gemfile
|
|
93
93
|
- lib/store_base_sti_class.rb
|
|
94
94
|
- lib/store_base_sti_class/version.rb
|
|
95
|
-
- lib/store_base_sti_class_for_4_2.rb
|
|
96
95
|
- lib/store_base_sti_class_for_5_0.rb
|
|
97
96
|
- lib/store_base_sti_class_for_5_1.rb
|
|
98
97
|
- lib/store_base_sti_class_for_5_2.rb
|
|
99
98
|
- lib/store_base_sti_class_for_6_0.rb
|
|
99
|
+
- lib/store_base_sti_class_for_6_1.rb
|
|
100
100
|
- store_base_sti_class.gemspec
|
|
101
101
|
homepage: http://github.com/appfolio/store_base_sti_class
|
|
102
102
|
licenses:
|
|
103
103
|
- MIT
|
|
104
104
|
metadata: {}
|
|
105
|
-
post_install_message:
|
|
105
|
+
post_install_message:
|
|
106
106
|
rdoc_options: []
|
|
107
107
|
require_paths:
|
|
108
108
|
- lib
|
|
@@ -117,8 +117,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
117
117
|
- !ruby/object:Gem::Version
|
|
118
118
|
version: '0'
|
|
119
119
|
requirements: []
|
|
120
|
-
rubygems_version: 3.
|
|
121
|
-
signing_key:
|
|
120
|
+
rubygems_version: 3.1.4
|
|
121
|
+
signing_key:
|
|
122
122
|
specification_version: 4
|
|
123
123
|
summary: Modifies ActiveRecord 4.2.x - 6.0.x with the ability to store the actual
|
|
124
124
|
class (instead of the base class) in polymorhic _type columns when using STI
|
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
require 'active_record/associations/join_dependency/join_part'
|
|
2
|
-
|
|
3
|
-
if ActiveRecord::VERSION::STRING =~ /^4\.2/
|
|
4
|
-
module ActiveRecord
|
|
5
|
-
|
|
6
|
-
class Base
|
|
7
|
-
class_attribute :store_base_sti_class
|
|
8
|
-
self.store_base_sti_class = true
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
module Associations
|
|
12
|
-
class Association
|
|
13
|
-
|
|
14
|
-
def creation_attributes
|
|
15
|
-
attributes = {}
|
|
16
|
-
|
|
17
|
-
if (reflection.has_one? || reflection.collection?) && !options[:through]
|
|
18
|
-
attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
|
|
19
|
-
|
|
20
|
-
if reflection.options[:as]
|
|
21
|
-
# START PATCH
|
|
22
|
-
# original:
|
|
23
|
-
# attributes[reflection.type] = owner.class.base_class.name
|
|
24
|
-
|
|
25
|
-
attributes[reflection.type] = ActiveRecord::Base.store_base_sti_class ? owner.class.base_class.name : owner.class.name
|
|
26
|
-
# END PATCH
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
attributes
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
class JoinDependency # :nodoc:
|
|
35
|
-
class JoinAssociation < JoinPart # :nodoc:
|
|
36
|
-
def join_constraints(foreign_table, foreign_klass, node, join_type, tables, scope_chain, chain)
|
|
37
|
-
joins = []
|
|
38
|
-
bind_values = []
|
|
39
|
-
tables = tables.reverse
|
|
40
|
-
|
|
41
|
-
scope_chain_index = 0
|
|
42
|
-
scope_chain = scope_chain.reverse
|
|
43
|
-
|
|
44
|
-
# The chain starts with the target table, but we want to end with it here (makes
|
|
45
|
-
# more sense in this context), so we reverse
|
|
46
|
-
chain.reverse_each do |reflection|
|
|
47
|
-
table = tables.shift
|
|
48
|
-
klass = reflection.klass
|
|
49
|
-
|
|
50
|
-
join_keys = reflection.join_keys(klass)
|
|
51
|
-
key = join_keys.key
|
|
52
|
-
foreign_key = join_keys.foreign_key
|
|
53
|
-
|
|
54
|
-
constraint = build_constraint(klass, table, key, foreign_table, foreign_key)
|
|
55
|
-
|
|
56
|
-
scope_chain_items = scope_chain[scope_chain_index].map do |item|
|
|
57
|
-
if item.is_a?(Relation)
|
|
58
|
-
item
|
|
59
|
-
else
|
|
60
|
-
ActiveRecord::Relation.create(klass, table).instance_exec(node, &item)
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
scope_chain_index += 1
|
|
64
|
-
|
|
65
|
-
scope_chain_items.concat [klass.send(:build_default_scope, ActiveRecord::Relation.create(klass, table))].compact
|
|
66
|
-
|
|
67
|
-
rel = scope_chain_items.inject(scope_chain_items.shift) do |left, right|
|
|
68
|
-
left.merge right
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
if rel && !rel.arel.constraints.empty?
|
|
72
|
-
bind_values.concat rel.bind_values
|
|
73
|
-
constraint = constraint.and rel.arel.constraints
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
if reflection.type
|
|
77
|
-
# START PATCH
|
|
78
|
-
# original:
|
|
79
|
-
# value = foreign_klass.base_class.name
|
|
80
|
-
value = ActiveRecord::Base.store_base_sti_class ? foreign_klass.base_class.name : foreign_klass.name
|
|
81
|
-
# END PATCH
|
|
82
|
-
column = klass.columns_hash[reflection.type.to_s]
|
|
83
|
-
|
|
84
|
-
substitute = klass.connection.substitute_at(column)
|
|
85
|
-
bind_values.push [column, value]
|
|
86
|
-
constraint = constraint.and table[reflection.type].eq substitute
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
joins << table.create_join(table, table.create_on(constraint), join_type)
|
|
90
|
-
|
|
91
|
-
# The current table in this iteration becomes the foreign table in the next
|
|
92
|
-
foreign_table, foreign_klass = table, klass
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
JoinInformation.new joins, bind_values
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
class BelongsToPolymorphicAssociation
|
|
101
|
-
private
|
|
102
|
-
|
|
103
|
-
def replace_keys(record)
|
|
104
|
-
super
|
|
105
|
-
|
|
106
|
-
# START PATCH
|
|
107
|
-
# original:
|
|
108
|
-
# owner[reflection.foreign_type] = record.class.base_class.name
|
|
109
|
-
|
|
110
|
-
owner[reflection.foreign_type] = ActiveRecord::Base.store_base_sti_class ? record.class.base_class.name : record.class.name
|
|
111
|
-
|
|
112
|
-
# END PATCH
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
class Preloader
|
|
117
|
-
class Association
|
|
118
|
-
|
|
119
|
-
def build_scope
|
|
120
|
-
scope = klass.unscoped
|
|
121
|
-
|
|
122
|
-
values = reflection_scope.values
|
|
123
|
-
reflection_binds = reflection_scope.bind_values
|
|
124
|
-
preload_values = preload_scope.values
|
|
125
|
-
preload_binds = preload_scope.bind_values
|
|
126
|
-
|
|
127
|
-
scope.where_values = Array(values[:where]) + Array(preload_values[:where])
|
|
128
|
-
scope.references_values = Array(values[:references]) + Array(preload_values[:references])
|
|
129
|
-
scope.bind_values = (reflection_binds + preload_binds)
|
|
130
|
-
|
|
131
|
-
scope._select! preload_values[:select] || values[:select] || table[Arel.star]
|
|
132
|
-
scope.includes! preload_values[:includes] || values[:includes]
|
|
133
|
-
scope.joins! preload_values[:joins] || values[:joins]
|
|
134
|
-
scope.order! preload_values[:order] || values[:order]
|
|
135
|
-
|
|
136
|
-
if preload_values[:readonly] || values[:readonly]
|
|
137
|
-
scope.readonly!
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
if options[:as]
|
|
141
|
-
# START PATCH
|
|
142
|
-
# original:
|
|
143
|
-
# scope.where!(klass.table_name => { reflection.type => model.base_class.sti_name })
|
|
144
|
-
|
|
145
|
-
scope.where!(klass.table_name => { reflection.type => ActiveRecord::Base.store_base_sti_class ? model.base_class.sti_name : model.sti_name })
|
|
146
|
-
|
|
147
|
-
# END PATCH
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
scope.unscope_values = Array(values[:unscope])
|
|
151
|
-
klass.default_scoped.merge(scope)
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
module ThroughAssociation
|
|
156
|
-
private
|
|
157
|
-
|
|
158
|
-
def through_scope
|
|
159
|
-
scope = through_reflection.klass.unscoped
|
|
160
|
-
|
|
161
|
-
if options[:source_type]
|
|
162
|
-
# BEGIN PATCH
|
|
163
|
-
# original: scope.where! reflection.foreign_type => options[:source_type]
|
|
164
|
-
|
|
165
|
-
adjusted_foreign_type = if ActiveRecord::Base.store_base_sti_class
|
|
166
|
-
options[:source_type]
|
|
167
|
-
else
|
|
168
|
-
([options[:source_type].constantize] + options[:source_type].constantize.descendants).map(&:to_s)
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
scope.where! reflection.foreign_type => adjusted_foreign_type
|
|
172
|
-
|
|
173
|
-
# END PATCH
|
|
174
|
-
else
|
|
175
|
-
unless reflection_scope.where_values.empty?
|
|
176
|
-
scope.includes_values = Array(reflection_scope.values[:includes] || options[:source])
|
|
177
|
-
scope.where_values = reflection_scope.values[:where]
|
|
178
|
-
scope.bind_values = reflection_scope.bind_values
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
scope.references! reflection_scope.values[:references]
|
|
182
|
-
scope = scope.order reflection_scope.values[:order] if scope.eager_loading?
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
scope
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
class AssociationScope
|
|
191
|
-
def self.get_bind_values(owner, chain)
|
|
192
|
-
binds = []
|
|
193
|
-
last_reflection = chain.last
|
|
194
|
-
|
|
195
|
-
binds << last_reflection.join_id_for(owner)
|
|
196
|
-
if last_reflection.type
|
|
197
|
-
# START PATCH
|
|
198
|
-
# original: binds << owner.class.base_class.name
|
|
199
|
-
binds << (ActiveRecord::Base.store_base_sti_class ? owner.class.base_class.name : owner.class.name)
|
|
200
|
-
# END PATCH
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
chain.each_cons(2).each do |reflection, next_reflection|
|
|
204
|
-
if reflection.type
|
|
205
|
-
# START PATCH
|
|
206
|
-
# original: binds << next_reflection.klass.base_class.name
|
|
207
|
-
binds << (ActiveRecord::Base.store_base_sti_class ? next_reflection.klass.base_class.name : next_reflection.klass.name)
|
|
208
|
-
# END PATCH
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
binds
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def next_chain_scope(scope, table, reflection, tracker, assoc_klass, foreign_table, next_reflection)
|
|
215
|
-
join_keys = reflection.join_keys(assoc_klass)
|
|
216
|
-
key = join_keys.key
|
|
217
|
-
foreign_key = join_keys.foreign_key
|
|
218
|
-
|
|
219
|
-
constraint = table[key].eq(foreign_table[foreign_key])
|
|
220
|
-
|
|
221
|
-
if reflection.type
|
|
222
|
-
# BEGIN PATCH
|
|
223
|
-
# original:
|
|
224
|
-
# value = next_reflection.klass.base_class.name
|
|
225
|
-
# bind_val = bind scope, table.table_name, reflection.type, value, tracker
|
|
226
|
-
# scope = scope.where(table[reflection.type].eq(bind_val))
|
|
227
|
-
if ActiveRecord::Base.store_base_sti_class
|
|
228
|
-
value = next_reflection.klass.base_class.name
|
|
229
|
-
bind_val = bind scope, table.table_name, reflection.type, value, tracker
|
|
230
|
-
scope = scope.where(table[reflection.type].eq(bind_val))
|
|
231
|
-
else
|
|
232
|
-
value = next_reflection.klass.name
|
|
233
|
-
klass = next_reflection.klass
|
|
234
|
-
scope = scope.where(table[reflection.type].in(([klass] + klass.descendants).map(&:name)))
|
|
235
|
-
end
|
|
236
|
-
# END PATCH
|
|
237
|
-
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
scope = scope.joins(join(foreign_table, constraint))
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
def last_chain_scope(scope, table, reflection, owner, tracker, assoc_klass)
|
|
244
|
-
join_keys = reflection.join_keys(assoc_klass)
|
|
245
|
-
key = join_keys.key
|
|
246
|
-
foreign_key = join_keys.foreign_key
|
|
247
|
-
|
|
248
|
-
bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key], tracker
|
|
249
|
-
scope = scope.where(table[key].eq(bind_val))
|
|
250
|
-
|
|
251
|
-
if reflection.type
|
|
252
|
-
# BEGIN PATCH
|
|
253
|
-
# original: owner.class.base_class.name
|
|
254
|
-
value = ActiveRecord::Base.store_base_sti_class ? owner.class.base_class.name : owner.class.name
|
|
255
|
-
# END PATCH
|
|
256
|
-
bind_val = bind scope, table.table_name, reflection.type, value, tracker
|
|
257
|
-
scope = scope.where(table[reflection.type].eq(bind_val))
|
|
258
|
-
else
|
|
259
|
-
scope
|
|
260
|
-
end
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
module ThroughAssociation
|
|
266
|
-
def construct_join_attributes(*records)
|
|
267
|
-
ensure_mutable
|
|
268
|
-
|
|
269
|
-
if source_reflection.association_primary_key(reflection.klass) == reflection.klass.primary_key
|
|
270
|
-
join_attributes = { source_reflection.name => records }
|
|
271
|
-
else
|
|
272
|
-
join_attributes = {
|
|
273
|
-
source_reflection.foreign_key =>
|
|
274
|
-
records.map { |record|
|
|
275
|
-
record.send(source_reflection.association_primary_key(reflection.klass))
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
if options[:source_type]
|
|
281
|
-
|
|
282
|
-
# START PATCH
|
|
283
|
-
# original:
|
|
284
|
-
# join_attributes[source_reflection.foreign_type] =
|
|
285
|
-
# records.map { |record| record.class.base_class.name }
|
|
286
|
-
|
|
287
|
-
join_attributes[source_reflection.foreign_type] =
|
|
288
|
-
records.map { |record| ActiveRecord::Base.store_base_sti_class ? record.class.base_class.name : record.class.name }
|
|
289
|
-
|
|
290
|
-
# END PATCH
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
if records.count == 1
|
|
294
|
-
Hash[join_attributes.map { |k, v| [k, v.first] }]
|
|
295
|
-
else
|
|
296
|
-
join_attributes
|
|
297
|
-
end
|
|
298
|
-
end
|
|
299
|
-
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
class HasManyThroughAssociation
|
|
303
|
-
|
|
304
|
-
def build_through_record(record)
|
|
305
|
-
@through_records[record.object_id] ||= begin
|
|
306
|
-
ensure_mutable
|
|
307
|
-
|
|
308
|
-
through_record = through_association.build(*options_for_through_record)
|
|
309
|
-
through_record.send("#{source_reflection.name}=", record)
|
|
310
|
-
|
|
311
|
-
# START PATCH
|
|
312
|
-
if ActiveRecord::Base.store_base_sti_class
|
|
313
|
-
if options[:source_type]
|
|
314
|
-
through_record.send("#{source_reflection.foreign_type}=", options[:source_type])
|
|
315
|
-
end
|
|
316
|
-
end
|
|
317
|
-
# END PATCH
|
|
318
|
-
|
|
319
|
-
through_record
|
|
320
|
-
end
|
|
321
|
-
end
|
|
322
|
-
end
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
module Reflection
|
|
326
|
-
class ThroughReflection
|
|
327
|
-
def scope_chain
|
|
328
|
-
@scope_chain ||= begin
|
|
329
|
-
scope_chain = source_reflection.scope_chain.map(&:dup)
|
|
330
|
-
|
|
331
|
-
# Add to it the scope from this reflection (if any)
|
|
332
|
-
scope_chain.first << scope if scope
|
|
333
|
-
|
|
334
|
-
through_scope_chain = through_reflection.scope_chain.map(&:dup)
|
|
335
|
-
|
|
336
|
-
if options[:source_type]
|
|
337
|
-
type = foreign_type
|
|
338
|
-
# START PATCH
|
|
339
|
-
# original: source_type = options[:source_type]
|
|
340
|
-
source_type = if ActiveRecord::Base.store_base_sti_class
|
|
341
|
-
options[:source_type]
|
|
342
|
-
else
|
|
343
|
-
([options[:source_type].constantize] + options[:source_type].constantize.descendants).map(&:to_s)
|
|
344
|
-
end
|
|
345
|
-
# END PATCH
|
|
346
|
-
through_scope_chain.first << lambda { |object|
|
|
347
|
-
where(type => source_type)
|
|
348
|
-
}
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
# Recursively fill out the rest of the array from the through reflection
|
|
352
|
-
scope_chain + through_scope_chain
|
|
353
|
-
end
|
|
354
|
-
end
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
end
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
end
|