activerecord 6.1.0 → 6.1.3.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +200 -15
- data/README.rdoc +1 -1
- data/lib/active_record/aggregations.rb +4 -4
- data/lib/active_record/association_relation.rb +10 -0
- data/lib/active_record/associations.rb +6 -2
- data/lib/active_record/associations/association.rb +7 -7
- data/lib/active_record/associations/association_scope.rb +7 -5
- data/lib/active_record/associations/belongs_to_association.rb +7 -3
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -2
- data/lib/active_record/associations/builder/association.rb +23 -2
- data/lib/active_record/associations/builder/belongs_to.rb +2 -2
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +8 -7
- data/lib/active_record/attributes.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +4 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +4 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +7 -1
- data/lib/active_record/connection_adapters/abstract_adapter.rb +7 -8
- data/lib/active_record/connection_adapters/mysql/quoting.rb +17 -2
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +4 -1
- data/lib/active_record/connection_adapters/pool_config.rb +13 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +2 -8
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -1
- data/lib/active_record/connection_handling.rb +20 -12
- data/lib/active_record/core.rb +42 -24
- data/lib/active_record/database_configurations/url_config.rb +1 -1
- data/lib/active_record/enum.rb +48 -28
- data/lib/active_record/fixtures.rb +5 -2
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/locking/optimistic.rb +14 -4
- data/lib/active_record/log_subscriber.rb +3 -2
- data/lib/active_record/migration.rb +1 -1
- data/lib/active_record/migration/compatibility.rb +2 -1
- data/lib/active_record/model_schema.rb +4 -4
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/databases.rake +13 -7
- data/lib/active_record/reflection.rb +1 -1
- data/lib/active_record/relation.rb +1 -2
- data/lib/active_record/relation/finder_methods.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +5 -6
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +3 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +9 -5
- data/lib/active_record/relation/query_methods.rb +8 -5
- data/lib/active_record/relation/where_clause.rb +5 -5
- data/lib/active_record/signed_id.rb +1 -1
- data/lib/active_record/table_metadata.rb +6 -3
- data/lib/active_record/tasks/database_tasks.rb +1 -0
- data/lib/active_record/transactions.rb +4 -2
- metadata +10 -10
@@ -42,7 +42,7 @@ module ActiveRecord
|
|
42
42
|
# Return a Hash that can be merged into the main config that represents
|
43
43
|
# the passed in url
|
44
44
|
def build_url_hash
|
45
|
-
if url.nil? || url.start_with?(
|
45
|
+
if url.nil? || %w(jdbc: http: https:).any? { |protocol| url.start_with?(protocol) }
|
46
46
|
{ url: url }
|
47
47
|
else
|
48
48
|
ConnectionUrlResolver.new(url).to_hash
|
data/lib/active_record/enum.rb
CHANGED
@@ -158,8 +158,6 @@ module ActiveRecord
|
|
158
158
|
end
|
159
159
|
|
160
160
|
def enum(definitions)
|
161
|
-
klass = self
|
162
|
-
|
163
161
|
enum_prefix = definitions.delete(:_prefix)
|
164
162
|
enum_suffix = definitions.delete(:_suffix)
|
165
163
|
enum_scopes = definitions.delete(:_scopes)
|
@@ -187,55 +185,77 @@ module ActiveRecord
|
|
187
185
|
EnumType.new(attr, enum_values, subtype)
|
188
186
|
end
|
189
187
|
|
188
|
+
value_method_names = []
|
190
189
|
_enum_methods_module.module_eval do
|
190
|
+
prefix = if enum_prefix == true
|
191
|
+
"#{name}_"
|
192
|
+
elsif enum_prefix
|
193
|
+
"#{enum_prefix}_"
|
194
|
+
end
|
195
|
+
|
196
|
+
suffix = if enum_suffix == true
|
197
|
+
"_#{name}"
|
198
|
+
elsif enum_suffix
|
199
|
+
"_#{enum_suffix}"
|
200
|
+
end
|
201
|
+
|
191
202
|
pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
|
192
|
-
value_method_names = []
|
193
203
|
pairs.each do |label, value|
|
194
|
-
if enum_prefix == true
|
195
|
-
prefix = "#{name}_"
|
196
|
-
elsif enum_prefix
|
197
|
-
prefix = "#{enum_prefix}_"
|
198
|
-
end
|
199
|
-
if enum_suffix == true
|
200
|
-
suffix = "_#{name}"
|
201
|
-
elsif enum_suffix
|
202
|
-
suffix = "_#{enum_suffix}"
|
203
|
-
end
|
204
|
-
|
205
|
-
method_friendly_label = label.to_s.gsub(/\W+/, "_")
|
206
|
-
value_method_name = "#{prefix}#{method_friendly_label}#{suffix}"
|
207
|
-
value_method_names << value_method_name
|
208
204
|
enum_values[label] = value
|
209
205
|
label = label.to_s
|
210
206
|
|
211
|
-
|
207
|
+
value_method_name = "#{prefix}#{label}#{suffix}"
|
208
|
+
value_method_names << value_method_name
|
209
|
+
define_enum_methods(name, value_method_name, value, enum_scopes)
|
210
|
+
|
211
|
+
method_friendly_label = label.gsub(/[\W&&[:ascii:]]+/, "_")
|
212
|
+
value_method_alias = "#{prefix}#{method_friendly_label}#{suffix}"
|
213
|
+
|
214
|
+
if value_method_alias != value_method_name && !value_method_names.include?(value_method_alias)
|
215
|
+
value_method_names << value_method_alias
|
216
|
+
define_enum_methods(name, value_method_alias, value, enum_scopes)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
detect_negative_enum_conditions!(value_method_names) if enum_scopes != false
|
221
|
+
enum_values.freeze
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
private
|
226
|
+
class EnumMethods < Module # :nodoc:
|
227
|
+
def initialize(klass)
|
228
|
+
@klass = klass
|
229
|
+
end
|
230
|
+
|
231
|
+
private
|
232
|
+
attr_reader :klass
|
233
|
+
|
234
|
+
def define_enum_methods(name, value_method_name, value, enum_scopes)
|
235
|
+
# def active?() status_for_database == 0 end
|
212
236
|
klass.send(:detect_enum_conflict!, name, "#{value_method_name}?")
|
213
|
-
define_method("#{value_method_name}?") {
|
237
|
+
define_method("#{value_method_name}?") { public_send(:"#{name}_for_database") == value }
|
214
238
|
|
215
239
|
# def active!() update!(status: 0) end
|
216
240
|
klass.send(:detect_enum_conflict!, name, "#{value_method_name}!")
|
217
|
-
define_method("#{value_method_name}!") { update!(
|
241
|
+
define_method("#{value_method_name}!") { update!(name => value) }
|
218
242
|
|
219
243
|
# scope :active, -> { where(status: 0) }
|
220
244
|
# scope :not_active, -> { where.not(status: 0) }
|
221
245
|
if enum_scopes != false
|
222
246
|
klass.send(:detect_enum_conflict!, name, value_method_name, true)
|
223
|
-
klass.scope value_method_name, -> { where(
|
247
|
+
klass.scope value_method_name, -> { where(name => value) }
|
224
248
|
|
225
249
|
klass.send(:detect_enum_conflict!, name, "not_#{value_method_name}", true)
|
226
|
-
klass.scope "not_#{value_method_name}", -> { where.not(
|
250
|
+
klass.scope "not_#{value_method_name}", -> { where.not(name => value) }
|
227
251
|
end
|
228
252
|
end
|
229
|
-
klass.send(:detect_negative_enum_conditions!, value_method_names) if enum_scopes != false
|
230
|
-
end
|
231
|
-
enum_values.freeze
|
232
253
|
end
|
233
|
-
|
254
|
+
private_constant :EnumMethods
|
234
255
|
|
235
|
-
private
|
236
256
|
def _enum_methods_module
|
237
257
|
@_enum_methods_module ||= begin
|
238
|
-
mod =
|
258
|
+
mod = EnumMethods.new(self)
|
239
259
|
include mod
|
240
260
|
mod
|
241
261
|
end
|
@@ -181,7 +181,7 @@ module ActiveRecord
|
|
181
181
|
# end
|
182
182
|
# end
|
183
183
|
#
|
184
|
-
# If you preload your test database with all fixture data (probably by running
|
184
|
+
# If you preload your test database with all fixture data (probably by running <tt>bin/rails db:fixtures:load</tt>)
|
185
185
|
# and use transactional tests, then you may omit all fixtures declarations in your test cases since
|
186
186
|
# all the data's already there and every case rolls back its changes.
|
187
187
|
#
|
@@ -773,9 +773,12 @@ module ActiveRecord
|
|
773
773
|
|
774
774
|
def find
|
775
775
|
raise FixtureClassNotFound, "No class attached to find." unless model_class
|
776
|
-
model_class.unscoped do
|
776
|
+
object = model_class.unscoped do
|
777
777
|
model_class.find(fixture[model_class.primary_key])
|
778
778
|
end
|
779
|
+
# Fixtures can't be eagerly loaded
|
780
|
+
object.instance_variable_set(:@strict_loading, false)
|
781
|
+
object
|
779
782
|
end
|
780
783
|
end
|
781
784
|
end
|
@@ -89,7 +89,9 @@ module ActiveRecord
|
|
89
89
|
|
90
90
|
begin
|
91
91
|
locking_column = self.class.locking_column
|
92
|
-
|
92
|
+
lock_attribute_was = @attributes[locking_column]
|
93
|
+
lock_value_for_database = _lock_value_for_database(locking_column)
|
94
|
+
|
93
95
|
attribute_names = attribute_names.dup if attribute_names.frozen?
|
94
96
|
attribute_names << locking_column
|
95
97
|
|
@@ -98,7 +100,7 @@ module ActiveRecord
|
|
98
100
|
affected_rows = self.class._update_record(
|
99
101
|
attributes_with_values(attribute_names),
|
100
102
|
@primary_key => id_in_database,
|
101
|
-
locking_column =>
|
103
|
+
locking_column => lock_value_for_database
|
102
104
|
)
|
103
105
|
|
104
106
|
if affected_rows != 1
|
@@ -109,7 +111,7 @@ module ActiveRecord
|
|
109
111
|
|
110
112
|
# If something went wrong, revert the locking_column value.
|
111
113
|
rescue Exception
|
112
|
-
|
114
|
+
@attributes[locking_column] = lock_attribute_was
|
113
115
|
raise
|
114
116
|
end
|
115
117
|
end
|
@@ -121,7 +123,7 @@ module ActiveRecord
|
|
121
123
|
|
122
124
|
affected_rows = self.class._delete_record(
|
123
125
|
@primary_key => id_in_database,
|
124
|
-
locking_column =>
|
126
|
+
locking_column => _lock_value_for_database(locking_column)
|
125
127
|
)
|
126
128
|
|
127
129
|
if affected_rows != 1
|
@@ -131,6 +133,14 @@ module ActiveRecord
|
|
131
133
|
affected_rows
|
132
134
|
end
|
133
135
|
|
136
|
+
def _lock_value_for_database(locking_column)
|
137
|
+
if will_save_change_to_attribute?(locking_column)
|
138
|
+
@attributes[locking_column].value_for_database
|
139
|
+
else
|
140
|
+
@attributes[locking_column].original_value_for_database
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
134
144
|
module ClassMethods
|
135
145
|
DEFAULT_LOCKING_COLUMN = "lock_version"
|
136
146
|
|
@@ -22,9 +22,10 @@ module ActiveRecord
|
|
22
22
|
def strict_loading_violation(event)
|
23
23
|
debug do
|
24
24
|
owner = event.payload[:owner]
|
25
|
-
association = event.payload[:
|
25
|
+
association = event.payload[:reflection].klass
|
26
|
+
name = event.payload[:reflection].name
|
26
27
|
|
27
|
-
color("Strict loading violation: #{
|
28
|
+
color("Strict loading violation: #{owner} is marked for strict loading. The #{association} association named :#{name} cannot be lazily loaded.", RED)
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
@@ -320,7 +320,7 @@ module ActiveRecord
|
|
320
320
|
# +table_name+. Passing a hash containing <tt>:from</tt> and <tt>:to</tt>
|
321
321
|
# as +default_or_changes+ will make this change reversible in the migration.
|
322
322
|
# * <tt>change_column_null(table_name, column_name, null, default = nil)</tt>:
|
323
|
-
# Sets or removes a
|
323
|
+
# Sets or removes a <tt>NOT NULL</tt> constraint on +column_name+. The +null+ flag
|
324
324
|
# indicates whether the value can be +NULL+. See
|
325
325
|
# ActiveRecord::ConnectionAdapters::SchemaStatements#change_column_null for
|
326
326
|
# details.
|
@@ -56,7 +56,8 @@ module ActiveRecord
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def add_reference(table_name, ref_name, **options)
|
59
|
-
ReferenceDefinition.new(ref_name, **options)
|
59
|
+
ReferenceDefinition.new(ref_name, **options)
|
60
|
+
.add_to(connection.update_table_definition(table_name, self))
|
60
61
|
end
|
61
62
|
alias :add_belongs_to :add_reference
|
62
63
|
|
@@ -122,9 +122,9 @@ module ActiveRecord
|
|
122
122
|
# :singleton-method: immutable_strings_by_default=
|
123
123
|
# :call-seq: immutable_strings_by_default=(bool)
|
124
124
|
#
|
125
|
-
# Determines whether columns should infer their type as
|
126
|
-
#
|
127
|
-
#
|
125
|
+
# Determines whether columns should infer their type as +:string+ or
|
126
|
+
# +:immutable_string+. This setting does not affect the behavior of
|
127
|
+
# <tt>attribute :foo, :string</tt>. Defaults to false.
|
128
128
|
|
129
129
|
included do
|
130
130
|
mattr_accessor :primary_key_prefix_type, instance_writer: false
|
@@ -316,7 +316,7 @@ module ActiveRecord
|
|
316
316
|
# self.ignored_columns = [:category]
|
317
317
|
# end
|
318
318
|
#
|
319
|
-
# The schema still contains
|
319
|
+
# The schema still contains "category", but now the model omits it, so any meta-driven code or
|
320
320
|
# schema caching will not attempt to use the column:
|
321
321
|
#
|
322
322
|
# Project.columns_hash["category"] => nil
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
ActiveRecord::
|
4
|
-
|
5
|
-
at_exit do
|
6
|
-
ActiveRecord::Base.connection.rollback_transaction
|
3
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.set_callback(:checkout, :after) do
|
4
|
+
begin_transaction(joinable: false)
|
7
5
|
end
|
@@ -361,17 +361,23 @@ db_namespace = namespace :db do
|
|
361
361
|
|
362
362
|
# Skipped when no database
|
363
363
|
ActiveRecord::Tasks::DatabaseTasks.migrate
|
364
|
+
|
364
365
|
if ActiveRecord::Base.dump_schema_after_migration
|
365
366
|
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, ActiveRecord::Base.schema_format)
|
366
367
|
end
|
367
|
-
|
368
368
|
rescue ActiveRecord::NoDatabaseError
|
369
|
-
|
370
|
-
ActiveRecord::Tasks::DatabaseTasks.
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
369
|
+
config_name = db_config.name
|
370
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current(db_config.env_name, config_name)
|
371
|
+
|
372
|
+
if File.exist?(ActiveRecord::Tasks::DatabaseTasks.dump_filename(config_name))
|
373
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(
|
374
|
+
db_config,
|
375
|
+
ActiveRecord::Base.schema_format,
|
376
|
+
nil
|
377
|
+
)
|
378
|
+
else
|
379
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate
|
380
|
+
end
|
375
381
|
|
376
382
|
seed = true
|
377
383
|
end
|
@@ -162,7 +162,7 @@ module ActiveRecord
|
|
162
162
|
# <tt>composed_of :balance, class_name: 'Money'</tt> returns <tt>'Money'</tt>
|
163
163
|
# <tt>has_many :clients</tt> returns <tt>'Client'</tt>
|
164
164
|
def class_name
|
165
|
-
@class_name ||= -(options[:class_name]
|
165
|
+
@class_name ||= -(options[:class_name] || derive_class_name).to_s
|
166
166
|
end
|
167
167
|
|
168
168
|
# Returns a list of scopes that should be applied for this Reflection
|
@@ -683,8 +683,7 @@ module ActiveRecord
|
|
683
683
|
end
|
684
684
|
|
685
685
|
def scope_for_create
|
686
|
-
hash =
|
687
|
-
hash.delete(klass.inheritance_column) if klass.finder_needs_type_condition?
|
686
|
+
hash = where_clause.to_h(klass.table_name, equality_only: true)
|
688
687
|
create_with_value.each { |k, v| hash[k.to_s] = v } unless create_with_value.empty?
|
689
688
|
hash
|
690
689
|
end
|
@@ -326,7 +326,7 @@ module ActiveRecord
|
|
326
326
|
# compared to the records in memory. If the relation is unloaded, an
|
327
327
|
# efficient existence query is performed, as in #exists?.
|
328
328
|
def include?(record)
|
329
|
-
if loaded? || offset_value || limit_value
|
329
|
+
if loaded? || offset_value || limit_value || having_clause.any?
|
330
330
|
records.include?(record)
|
331
331
|
else
|
332
332
|
record.is_a?(klass) && exists?(record.id)
|
@@ -93,11 +93,8 @@ module ActiveRecord
|
|
93
93
|
# PriceEstimate.where(estimate_of: treasure)
|
94
94
|
associated_table = table.associated_table(key)
|
95
95
|
if associated_table.polymorphic_association?
|
96
|
-
|
97
|
-
|
98
|
-
value = [value] unless value.is_a?(Array)
|
99
|
-
klass = PolymorphicArrayValue
|
100
|
-
end
|
96
|
+
value = [value] unless value.is_a?(Array)
|
97
|
+
klass = PolymorphicArrayValue
|
101
98
|
elsif associated_table.through_association?
|
102
99
|
next associated_table.predicate_builder.expand_from_hash(
|
103
100
|
associated_table.primary_key => value
|
@@ -106,7 +103,9 @@ module ActiveRecord
|
|
106
103
|
|
107
104
|
klass ||= AssociationQueryValue
|
108
105
|
queries = klass.new(associated_table, value).queries.map! do |query|
|
109
|
-
|
106
|
+
# If the query produced is identical to attributes don't go any deeper.
|
107
|
+
# Prevents stack level too deep errors when association and foreign_key are identical.
|
108
|
+
query == attributes ? self[key, value] : expand_from_hash(query)
|
110
109
|
end
|
111
110
|
|
112
111
|
grouping_queries(queries)
|
@@ -9,7 +9,7 @@ module ActiveRecord
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def queries
|
12
|
-
[associated_table.join_foreign_key => ids]
|
12
|
+
[ associated_table.join_foreign_key => ids ]
|
13
13
|
end
|
14
14
|
|
15
15
|
private
|
@@ -31,8 +31,8 @@ module ActiveRecord
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def convert_to_id(value)
|
34
|
-
if value.respond_to?(
|
35
|
-
value.
|
34
|
+
if value.respond_to?(primary_key)
|
35
|
+
value.public_send(primary_key)
|
36
36
|
else
|
37
37
|
value
|
38
38
|
end
|
@@ -9,11 +9,13 @@ module ActiveRecord
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def queries
|
12
|
+
return [ associated_table.join_foreign_key => values ] if values.empty?
|
13
|
+
|
12
14
|
type_to_ids_mapping.map do |type, ids|
|
13
|
-
{
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
query = {}
|
16
|
+
query[associated_table.join_foreign_type] = type if type
|
17
|
+
query[associated_table.join_foreign_key] = ids
|
18
|
+
query
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
@@ -23,7 +25,7 @@ module ActiveRecord
|
|
23
25
|
def type_to_ids_mapping
|
24
26
|
default_hash = Hash.new { |hsh, key| hsh[key] = [] }
|
25
27
|
values.each_with_object(default_hash) do |value, hash|
|
26
|
-
hash[klass(value)
|
28
|
+
hash[klass(value)&.polymorphic_name] << convert_to_id(value)
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
@@ -46,6 +48,8 @@ module ActiveRecord
|
|
46
48
|
value._read_attribute(primary_key(value))
|
47
49
|
when Relation
|
48
50
|
value.select(primary_key(value))
|
51
|
+
else
|
52
|
+
value
|
49
53
|
end
|
50
54
|
end
|
51
55
|
end
|
@@ -1081,12 +1081,15 @@ module ActiveRecord
|
|
1081
1081
|
when String, Array
|
1082
1082
|
parts = [klass.sanitize_sql(rest.empty? ? opts : [opts, *rest])]
|
1083
1083
|
when Hash
|
1084
|
-
opts = opts.
|
1084
|
+
opts = opts.transform_keys do |key|
|
1085
|
+
key = key.to_s
|
1086
|
+
klass.attribute_aliases[key] || key
|
1087
|
+
end
|
1085
1088
|
references = PredicateBuilder.references(opts)
|
1086
1089
|
self.references_values |= references unless references.empty?
|
1087
1090
|
|
1088
1091
|
parts = predicate_builder.build_from_hash(opts) do |table_name|
|
1089
|
-
|
1092
|
+
lookup_table_klass_from_join_dependencies(table_name)
|
1090
1093
|
end
|
1091
1094
|
when Arel::Nodes::Node
|
1092
1095
|
parts = [opts]
|
@@ -1099,9 +1102,9 @@ module ActiveRecord
|
|
1099
1102
|
alias :build_having_clause :build_where_clause
|
1100
1103
|
|
1101
1104
|
private
|
1102
|
-
def
|
1105
|
+
def lookup_table_klass_from_join_dependencies(table_name)
|
1103
1106
|
each_join_dependencies do |join|
|
1104
|
-
return join.
|
1107
|
+
return join.base_klass if table_name == join.table_name
|
1105
1108
|
end
|
1106
1109
|
nil
|
1107
1110
|
end
|
@@ -1312,7 +1315,7 @@ module ActiveRecord
|
|
1312
1315
|
elsif field.match?(/\A\w+\.\w+\z/)
|
1313
1316
|
table, column = field.split(".")
|
1314
1317
|
predicate_builder.resolve_arel_attribute(table, column) do
|
1315
|
-
|
1318
|
+
lookup_table_klass_from_join_dependencies(table)
|
1316
1319
|
end
|
1317
1320
|
else
|
1318
1321
|
yield field
|