activerecord 5.0.0.1 → 5.0.1.rc1
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 +196 -2
- data/README.rdoc +1 -1
- data/lib/active_record.rb +1 -1
- data/lib/active_record/aggregations.rb +4 -2
- data/lib/active_record/association_relation.rb +4 -1
- data/lib/active_record/associations.rb +5 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +4 -2
- data/lib/active_record/associations/builder/singular_association.rb +10 -1
- data/lib/active_record/associations/collection_association.rb +22 -17
- data/lib/active_record/associations/collection_proxy.rb +20 -7
- data/lib/active_record/associations/has_many_through_association.rb +4 -0
- data/lib/active_record/associations/join_dependency.rb +10 -4
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/preloader/association.rb +18 -4
- data/lib/active_record/associations/preloader/collection_association.rb +0 -1
- data/lib/active_record/associations/preloader/singular_association.rb +0 -1
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/attribute.rb +3 -3
- data/lib/active_record/attribute_methods.rb +3 -7
- data/lib/active_record/attribute_methods/primary_key.rb +14 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
- data/lib/active_record/attribute_set.rb +2 -0
- data/lib/active_record/attribute_set/builder.rb +29 -7
- data/lib/active_record/attributes.rb +3 -3
- data/lib/active_record/autosave_association.rb +15 -11
- data/lib/active_record/base.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +40 -32
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +29 -0
- data/lib/active_record/connection_adapters/abstract/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +8 -7
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +37 -33
- data/lib/active_record/connection_adapters/abstract_adapter.rb +28 -5
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +42 -45
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +6 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -5
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +12 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +7 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +6 -2
- data/lib/active_record/core.rb +3 -1
- data/lib/active_record/enum.rb +6 -5
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/integration.rb +13 -10
- data/lib/active_record/migration.rb +6 -5
- data/lib/active_record/model_schema.rb +134 -47
- data/lib/active_record/no_touching.rb +4 -0
- data/lib/active_record/persistence.rb +10 -4
- data/lib/active_record/query_cache.rb +13 -15
- data/lib/active_record/querying.rb +3 -3
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/reflection.rb +8 -0
- data/lib/active_record/relation.rb +7 -4
- data/lib/active_record/relation/calculations.rb +11 -11
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +11 -9
- data/lib/active_record/relation/query_methods.rb +3 -3
- data/lib/active_record/result.rb +7 -1
- data/lib/active_record/sanitization.rb +11 -1
- data/lib/active_record/schema_dumper.rb +10 -17
- data/lib/active_record/scoping/named.rb +1 -1
- data/lib/active_record/statement_cache.rb +2 -2
- data/lib/active_record/table_metadata.rb +4 -3
- data/lib/active_record/touch_later.rb +6 -1
- data/lib/active_record/type/internal/abstract_json.rb +5 -1
- data/lib/active_record/validations/uniqueness.rb +3 -4
- metadata +9 -10
@@ -63,10 +63,10 @@ module ActiveRecord
|
|
63
63
|
#
|
64
64
|
# See <tt>ActiveRecord::Inheritance#discriminate_class_for_record</tt> to see
|
65
65
|
# how this "single-table" inheritance mapping is implemented.
|
66
|
-
def instantiate(attributes, column_types = {})
|
66
|
+
def instantiate(attributes, column_types = {}, &block)
|
67
67
|
klass = discriminate_class_for_record(attributes)
|
68
68
|
attributes = klass.attributes_builder.build_from_database(attributes, column_types)
|
69
|
-
klass.allocate.init_with(
|
69
|
+
klass.allocate.init_with("attributes" => attributes, "new_record" => false, &block)
|
70
70
|
end
|
71
71
|
|
72
72
|
private
|
@@ -252,7 +252,8 @@ module ActiveRecord
|
|
252
252
|
name = name.to_s
|
253
253
|
verify_readonly_attribute(name)
|
254
254
|
public_send("#{name}=", value)
|
255
|
-
|
255
|
+
|
256
|
+
changed? ? save(validate: false) : true
|
256
257
|
end
|
257
258
|
|
258
259
|
# Updates the attributes of the model from the passed-in hash and saves the
|
@@ -479,7 +480,12 @@ module ActiveRecord
|
|
479
480
|
# ball.touch(:updated_at) # => raises ActiveRecordError
|
480
481
|
#
|
481
482
|
def touch(*names, time: nil)
|
482
|
-
|
483
|
+
unless persisted?
|
484
|
+
raise ActiveRecordError, <<-MSG.squish
|
485
|
+
cannot touch on a new or destroyed record object. Consider using
|
486
|
+
persisted?, new_record?, or destroyed? before touching
|
487
|
+
MSG
|
488
|
+
end
|
483
489
|
|
484
490
|
time ||= current_time_from_proper_timezone
|
485
491
|
attributes = timestamp_attributes_for_update_in_model
|
@@ -24,30 +24,28 @@ module ActiveRecord
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.run
|
27
|
-
connection = ActiveRecord::Base.connection
|
28
|
-
enabled = connection.query_cache_enabled
|
29
27
|
connection_id = ActiveRecord::Base.connection_id
|
30
|
-
connection.enable_query_cache!
|
31
28
|
|
32
|
-
|
33
|
-
|
29
|
+
caching_pool = ActiveRecord::Base.connection_pool
|
30
|
+
caching_was_enabled = caching_pool.query_cache_enabled
|
31
|
+
|
32
|
+
caching_pool.enable_query_cache!
|
34
33
|
|
35
|
-
|
36
|
-
|
34
|
+
[caching_pool, caching_was_enabled, connection_id]
|
35
|
+
end
|
37
36
|
|
37
|
+
def self.complete((caching_pool, caching_was_enabled, connection_id))
|
38
38
|
ActiveRecord::Base.connection_id = connection_id
|
39
|
-
|
40
|
-
|
39
|
+
|
40
|
+
caching_pool.disable_query_cache! unless caching_was_enabled
|
41
|
+
|
42
|
+
ActiveRecord::Base.connection_handler.connection_pool_list.each do |pool|
|
43
|
+
pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
|
44
|
+
end
|
41
45
|
end
|
42
46
|
|
43
47
|
def self.install_executor_hooks(executor = ActiveSupport::Executor)
|
44
48
|
executor.register_hook(self)
|
45
|
-
|
46
|
-
executor.to_complete do
|
47
|
-
unless ActiveRecord::Base.connection.transaction_open?
|
48
|
-
ActiveRecord::Base.clear_active_connections!
|
49
|
-
end
|
50
|
-
end
|
51
49
|
end
|
52
50
|
end
|
53
51
|
end
|
@@ -35,7 +35,7 @@ module ActiveRecord
|
|
35
35
|
#
|
36
36
|
# Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
|
37
37
|
# Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
|
38
|
-
def find_by_sql(sql, binds = [], preparable: nil)
|
38
|
+
def find_by_sql(sql, binds = [], preparable: nil, &block)
|
39
39
|
result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
|
40
40
|
column_types = result_set.column_types.dup
|
41
41
|
columns_hash.each_key { |k| column_types.delete k }
|
@@ -46,8 +46,8 @@ module ActiveRecord
|
|
46
46
|
class_name: name
|
47
47
|
}
|
48
48
|
|
49
|
-
message_bus.instrument(
|
50
|
-
result_set.map { |record| instantiate(record, column_types) }
|
49
|
+
message_bus.instrument("instantiation.active_record", payload) do
|
50
|
+
result_set.map { |record| instantiate(record, column_types, &block) }
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -19,7 +19,7 @@ module ActiveRecord
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def cleanup_view_runtime
|
22
|
-
if logger.info? && ActiveRecord::Base.connected?
|
22
|
+
if logger && logger.info? && ActiveRecord::Base.connected?
|
23
23
|
db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
|
24
24
|
self.db_runtime = (db_runtime || 0) + db_rt_before_render
|
25
25
|
runtime = super
|
@@ -311,6 +311,10 @@ module ActiveRecord
|
|
311
311
|
active_record == other_aggregation.active_record
|
312
312
|
end
|
313
313
|
|
314
|
+
def scope_for(klass)
|
315
|
+
scope ? klass.unscoped.instance_exec(nil, &scope) : klass.unscoped
|
316
|
+
end
|
317
|
+
|
314
318
|
private
|
315
319
|
def derive_class_name
|
316
320
|
name.to_s.camelize
|
@@ -394,6 +398,10 @@ module ActiveRecord
|
|
394
398
|
options[:primary_key] || primary_key(klass || self.klass)
|
395
399
|
end
|
396
400
|
|
401
|
+
def association_primary_key_type
|
402
|
+
klass.type_for_attribute(association_primary_key)
|
403
|
+
end
|
404
|
+
|
397
405
|
def active_record_primary_key
|
398
406
|
@active_record_primary_key ||= options[:primary_key] || primary_key(active_record)
|
399
407
|
end
|
@@ -372,6 +372,9 @@ module ActiveRecord
|
|
372
372
|
#
|
373
373
|
# # Update all books that match conditions, but limit it to 5 ordered by date
|
374
374
|
# Book.where('title LIKE ?', '%Rails%').order(:created_at).limit(5).update_all(author: 'David')
|
375
|
+
#
|
376
|
+
# # Update all invoices and set the number column to its id value.
|
377
|
+
# Invoice.update_all('number = id')
|
375
378
|
def update_all(updates)
|
376
379
|
raise ArgumentError, "Empty list of attributes to change" if updates.blank?
|
377
380
|
|
@@ -576,8 +579,8 @@ module ActiveRecord
|
|
576
579
|
# return value is the relation itself, not the records.
|
577
580
|
#
|
578
581
|
# Post.where(published: true).load # => #<ActiveRecord::Relation>
|
579
|
-
def load
|
580
|
-
exec_queries unless loaded?
|
582
|
+
def load(&block)
|
583
|
+
exec_queries(&block) unless loaded?
|
581
584
|
|
582
585
|
self
|
583
586
|
end
|
@@ -695,8 +698,8 @@ module ActiveRecord
|
|
695
698
|
|
696
699
|
private
|
697
700
|
|
698
|
-
def exec_queries
|
699
|
-
@records = eager_loading? ? find_with_associations.freeze : @klass.find_by_sql(arel, bound_attributes).freeze
|
701
|
+
def exec_queries(&block)
|
702
|
+
@records = eager_loading? ? find_with_associations.freeze : @klass.find_by_sql(arel, bound_attributes, &block).freeze
|
700
703
|
|
701
704
|
preload = preload_values
|
702
705
|
preload += includes_values unless eager_loading?
|
@@ -113,7 +113,10 @@ module ActiveRecord
|
|
113
113
|
end
|
114
114
|
|
115
115
|
if has_include?(column_name)
|
116
|
-
construct_relation_for_association_calculations
|
116
|
+
relation = construct_relation_for_association_calculations
|
117
|
+
relation = relation.distinct if operation.to_s.downcase == "count"
|
118
|
+
|
119
|
+
relation.calculate(operation, column_name)
|
117
120
|
else
|
118
121
|
perform_calculation(operation, column_name)
|
119
122
|
end
|
@@ -156,7 +159,7 @@ module ActiveRecord
|
|
156
159
|
#
|
157
160
|
def pluck(*column_names)
|
158
161
|
if loaded? && (column_names.map(&:to_s) - @klass.attribute_names - @klass.attribute_aliases.keys).empty?
|
159
|
-
return
|
162
|
+
return records.pluck(*column_names)
|
160
163
|
end
|
161
164
|
|
162
165
|
if has_include?(column_names.first)
|
@@ -194,11 +197,6 @@ module ActiveRecord
|
|
194
197
|
|
195
198
|
if operation == "count"
|
196
199
|
column_name ||= select_for_count
|
197
|
-
|
198
|
-
unless arel.ast.grep(Arel::Nodes::OuterJoin).empty?
|
199
|
-
distinct = true
|
200
|
-
end
|
201
|
-
|
202
200
|
column_name = primary_key if column_name == :all && distinct
|
203
201
|
distinct = nil if column_name =~ /\s*DISTINCT[\s(]+/i
|
204
202
|
end
|
@@ -308,8 +306,10 @@ module ActiveRecord
|
|
308
306
|
|
309
307
|
Hash[calculated_data.map do |row|
|
310
308
|
key = group_columns.map { |aliaz, col_name|
|
311
|
-
column =
|
312
|
-
|
309
|
+
column = type_for(col_name) do
|
310
|
+
calculated_data.column_types.fetch(aliaz) do
|
311
|
+
Type::Value.new
|
312
|
+
end
|
313
313
|
end
|
314
314
|
type_cast_calculated_value(row[aliaz], column)
|
315
315
|
}
|
@@ -342,9 +342,9 @@ module ActiveRecord
|
|
342
342
|
@klass.connection.table_alias_for(table_name)
|
343
343
|
end
|
344
344
|
|
345
|
-
def type_for(field)
|
345
|
+
def type_for(field, &block)
|
346
346
|
field_name = field.respond_to?(:name) ? field.name.to_s : field.to_s.split('.').last
|
347
|
-
@klass.type_for_attribute(field_name)
|
347
|
+
@klass.type_for_attribute(field_name, &block)
|
348
348
|
end
|
349
349
|
|
350
350
|
def type_cast_calculated_value(value, type, operation = nil)
|
@@ -37,7 +37,7 @@ module ActiveRecord
|
|
37
37
|
|
38
38
|
delegate :to_xml, :encode_with, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join,
|
39
39
|
:[], :&, :|, :+, :-, :sample, :reverse, :compact, :in_groups, :in_groups_of,
|
40
|
-
:shuffle, :split, to: :records
|
40
|
+
:shuffle, :split, :index, to: :records
|
41
41
|
|
42
42
|
delegate :table_name, :quoted_table_name, :primary_key, :quoted_primary_key,
|
43
43
|
:connection, :columns_hash, :to => :klass
|
@@ -343,18 +343,20 @@ module ActiveRecord
|
|
343
343
|
# of results obtained should be provided in the +result_size+ argument and
|
344
344
|
# the expected number of results should be provided in the +expected_size+
|
345
345
|
# argument.
|
346
|
-
def raise_record_not_found_exception!(ids, result_size, expected_size) #:nodoc:
|
346
|
+
def raise_record_not_found_exception!(ids, result_size, expected_size, key = primary_key) #:nodoc:
|
347
347
|
conditions = arel.where_sql(@klass.arel_engine)
|
348
348
|
conditions = " [#{conditions}]" if conditions
|
349
|
+
name = @klass.name
|
349
350
|
|
350
351
|
if Array(ids).size == 1
|
351
|
-
error = "Couldn't find #{
|
352
|
+
error = "Couldn't find #{name} with '#{key}'=#{ids}#{conditions}"
|
353
|
+
raise RecordNotFound.new(error, name, key, ids)
|
352
354
|
else
|
353
|
-
error = "Couldn't find all #{
|
355
|
+
error = "Couldn't find all #{name.pluralize} with '#{key}': "
|
354
356
|
error << "(#{ids.join(", ")})#{conditions} (found #{result_size} results, but was looking for #{expected_size})"
|
355
|
-
end
|
356
357
|
|
357
|
-
|
358
|
+
raise RecordNotFound, error
|
359
|
+
end
|
358
360
|
end
|
359
361
|
|
360
362
|
private
|
@@ -520,7 +522,7 @@ module ActiveRecord
|
|
520
522
|
|
521
523
|
def find_take
|
522
524
|
if loaded?
|
523
|
-
|
525
|
+
records.first
|
524
526
|
else
|
525
527
|
@take ||= limit(1).records.first
|
526
528
|
end
|
@@ -537,7 +539,7 @@ module ActiveRecord
|
|
537
539
|
MSG
|
538
540
|
end
|
539
541
|
if loaded?
|
540
|
-
|
542
|
+
records[index]
|
541
543
|
else
|
542
544
|
offset ||= offset_index
|
543
545
|
@offsets[offset + index] ||= find_nth_with_limit_and_offset(index, 1, offset: offset).first
|
@@ -563,7 +565,7 @@ module ActiveRecord
|
|
563
565
|
|
564
566
|
def find_nth_from_last(index)
|
565
567
|
if loaded?
|
566
|
-
|
568
|
+
records[-index]
|
567
569
|
else
|
568
570
|
relation = if order_values.empty? && primary_key
|
569
571
|
order(arel_attribute(primary_key).asc)
|
@@ -584,7 +586,7 @@ module ActiveRecord
|
|
584
586
|
|
585
587
|
def find_nth_with_limit_and_offset(index, limit, offset:) # :nodoc:
|
586
588
|
if loaded?
|
587
|
-
|
589
|
+
records[index, limit]
|
588
590
|
else
|
589
591
|
index += offset
|
590
592
|
find_nth_with_limit(index, limit)
|
@@ -1141,9 +1141,9 @@ module ActiveRecord
|
|
1141
1141
|
end
|
1142
1142
|
|
1143
1143
|
def does_not_support_reverse?(order)
|
1144
|
-
#
|
1145
|
-
order
|
1146
|
-
#
|
1144
|
+
# Uses SQL function with multiple arguments.
|
1145
|
+
(order.include?(',') && order.split(',').find { |section| section.count('(') != section.count(')')}) ||
|
1146
|
+
# Uses "nulls first" like construction.
|
1147
1147
|
order =~ /nulls (first|last)\Z/i
|
1148
1148
|
end
|
1149
1149
|
|
data/lib/active_record/result.rb
CHANGED
@@ -75,8 +75,14 @@ module ActiveRecord
|
|
75
75
|
hash_rows[idx]
|
76
76
|
end
|
77
77
|
|
78
|
+
def first
|
79
|
+
return nil if @rows.empty?
|
80
|
+
Hash[@columns.zip(@rows.first)]
|
81
|
+
end
|
82
|
+
|
78
83
|
def last
|
79
|
-
|
84
|
+
return nil if @rows.empty?
|
85
|
+
Hash[@columns.zip(@rows.last)]
|
80
86
|
end
|
81
87
|
|
82
88
|
def cast_values(type_overrides = {}) # :nodoc:
|
@@ -116,7 +116,17 @@ module ActiveRecord
|
|
116
116
|
def sanitize_sql_hash_for_assignment(attrs, table)
|
117
117
|
c = connection
|
118
118
|
attrs.map do |attr, value|
|
119
|
-
value
|
119
|
+
if value.is_a?(Base)
|
120
|
+
require "active_support/core_ext/string/filters"
|
121
|
+
ActiveSupport::Deprecation.warn(<<-WARNING.squish)
|
122
|
+
Passing `ActiveRecord::Base` objects to
|
123
|
+
`sanitize_sql_hash_for_assignment` (or methods which call it,
|
124
|
+
such as `update_all`) is deprecated. Please pass the id directly,
|
125
|
+
instead.
|
126
|
+
WARNING
|
127
|
+
else
|
128
|
+
value = type_for_attribute(attr.to_s).serialize(value)
|
129
|
+
end
|
120
130
|
"#{c.quote_table_name_for_assignment(table, attr)} = #{c.quote(value)}"
|
121
131
|
end.join(', ')
|
122
132
|
end
|
@@ -105,12 +105,7 @@ HEADER
|
|
105
105
|
tbl = StringIO.new
|
106
106
|
|
107
107
|
# first dump primary key column
|
108
|
-
|
109
|
-
pk = @connection.primary_keys(table)
|
110
|
-
pk = pk.first unless pk.size > 1
|
111
|
-
else
|
112
|
-
pk = @connection.primary_key(table)
|
113
|
-
end
|
108
|
+
pk = @connection.primary_key(table)
|
114
109
|
|
115
110
|
tbl.print " create_table #{remove_prefix_and_suffix(table).inspect}"
|
116
111
|
|
@@ -132,10 +127,8 @@ HEADER
|
|
132
127
|
tbl.print ", force: :cascade"
|
133
128
|
|
134
129
|
table_options = @connection.table_options(table)
|
135
|
-
|
136
|
-
|
137
|
-
if comment = @connection.table_comment(table).presence
|
138
|
-
tbl.print ", comment: #{comment.inspect}"
|
130
|
+
if table_options.present?
|
131
|
+
tbl.print ", #{format_options(table_options)}"
|
139
132
|
end
|
140
133
|
|
141
134
|
tbl.puts " do |t|"
|
@@ -218,13 +211,9 @@ HEADER
|
|
218
211
|
index.columns.inspect,
|
219
212
|
"name: #{index.name.inspect}",
|
220
213
|
]
|
221
|
-
index_parts <<
|
222
|
-
|
223
|
-
|
224
|
-
index_parts << "length: #{Hash[index.columns.zip(index.lengths)].inspect}" if index_lengths.any?
|
225
|
-
|
226
|
-
index_orders = index.orders || {}
|
227
|
-
index_parts << "order: #{index.orders.inspect}" if index_orders.any?
|
214
|
+
index_parts << "unique: true" if index.unique
|
215
|
+
index_parts << "length: { #{format_options(index.lengths)} }" if index.lengths.present?
|
216
|
+
index_parts << "order: { #{format_options(index.orders)} }" if index.orders.present?
|
228
217
|
index_parts << "where: #{index.where.inspect}" if index.where
|
229
218
|
index_parts << "using: #{index.using.inspect}" if index.using
|
230
219
|
index_parts << "type: #{index.type.inspect}" if index.type
|
@@ -262,6 +251,10 @@ HEADER
|
|
262
251
|
end
|
263
252
|
end
|
264
253
|
|
254
|
+
def format_options(options)
|
255
|
+
options.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
|
256
|
+
end
|
257
|
+
|
265
258
|
def remove_prefix_and_suffix(table)
|
266
259
|
table.gsub(/^(#{@options[:table_name_prefix]})(.+)(#{@options[:table_name_suffix]})$/, "\\2")
|
267
260
|
end
|
@@ -101,12 +101,12 @@ module ActiveRecord
|
|
101
101
|
@bind_map = bind_map
|
102
102
|
end
|
103
103
|
|
104
|
-
def execute(params, klass, connection)
|
104
|
+
def execute(params, klass, connection, &block)
|
105
105
|
bind_values = bind_map.bind params
|
106
106
|
|
107
107
|
sql = query_builder.sql_for bind_values, connection
|
108
108
|
|
109
|
-
klass.find_by_sql(sql, bind_values, preparable: true)
|
109
|
+
klass.find_by_sql(sql, bind_values, preparable: true, &block)
|
110
110
|
end
|
111
111
|
alias :call :execute
|
112
112
|
end
|
@@ -42,10 +42,11 @@ module ActiveRecord
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def associated_table(table_name)
|
45
|
-
|
45
|
+
association = klass._reflect_on_association(table_name) || klass._reflect_on_association(table_name.singularize)
|
46
46
|
|
47
|
-
association
|
48
|
-
|
47
|
+
if !association && table_name == arel_table.name
|
48
|
+
return self
|
49
|
+
elsif association && !association.polymorphic?
|
49
50
|
association_klass = association.klass
|
50
51
|
arel_table = association_klass.arel_table.alias(table_name)
|
51
52
|
else
|