aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/core.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/core.rb')
-rw-r--r--activerecord/lib/active_record/core.rb69
1 files changed, 35 insertions, 34 deletions
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index a7aff9f724..1244bd6195 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -88,7 +88,6 @@ module ActiveRecord
mattr_accessor :maintain_test_schema, instance_accessor: false
class_attribute :default_connection_handler, instance_writer: false
- class_attribute :find_by_statement_cache
def self.connection_handler
ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler
@@ -107,20 +106,19 @@ module ActiveRecord
super
end
- def initialize_find_by_cache
- self.find_by_statement_cache = {}.extend(Mutex_m)
+ def initialize_find_by_cache # :nodoc:
+ @find_by_statement_cache = {}.extend(Mutex_m)
end
- def inherited(child_class)
+ def inherited(child_class) # :nodoc:
+ # initialize cache at class definition for thread safety
child_class.initialize_find_by_cache
super
end
- def find(*ids)
+ def find(*ids) # :nodoc:
# We don't have cache keys for this stuff yet
return super unless ids.length == 1
- # Allow symbols to super to maintain compatibility for deprecated finders until Rails 5
- return super if ids.first.kind_of?(Symbol)
return super if block_given? ||
primary_key.nil? ||
default_scopes.any? ||
@@ -136,14 +134,13 @@ module ActiveRecord
Please pass the id of the object by calling `.id`
MSG
end
+
key = primary_key
- s = find_by_statement_cache[key] || find_by_statement_cache.synchronize {
- find_by_statement_cache[key] ||= StatementCache.create(connection) { |params|
- where(key => params.bind).limit(1)
- }
+ statement = cached_find_by_statement(key) { |params|
+ where(key => params.bind).limit(1)
}
- record = s.execute([id], self, connection).first
+ record = statement.execute([id], self, connection).first
unless record
raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}"
end
@@ -152,7 +149,7 @@ module ActiveRecord
raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
end
- def find_by(*args)
+ def find_by(*args) # :nodoc:
return super if current_scope || !(Hash === args.first) || reflect_on_all_aggregations.any?
return super if default_scopes.any?
@@ -165,19 +162,16 @@ module ActiveRecord
# We can't cache Post.find_by(author: david) ...yet
return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) }
- key = hash.keys
+ keys = hash.keys
- klass = self
- s = find_by_statement_cache[key] || find_by_statement_cache.synchronize {
- find_by_statement_cache[key] ||= StatementCache.create(connection) { |params|
- wheres = key.each_with_object({}) { |param,o|
- o[param] = params.bind
- }
- klass.where(wheres).limit(1)
+ statement = cached_find_by_statement(keys) { |params|
+ wheres = keys.each_with_object({}) { |param, o|
+ o[param] = params.bind
}
+ where(wheres).limit(1)
}
begin
- s.execute(hash.values, self, connection).first
+ statement.execute(hash.values, self, connection).first
rescue TypeError => e
raise ActiveRecord::StatementInvalid.new(e.message, e)
rescue RangeError
@@ -185,11 +179,11 @@ module ActiveRecord
end
end
- def find_by!(*args)
+ def find_by!(*args) # :nodoc:
find_by(*args) or raise RecordNotFound.new("Couldn't find #{name}")
end
- def initialize_generated_modules
+ def initialize_generated_modules # :nodoc:
generated_association_methods
end
@@ -210,7 +204,7 @@ module ActiveRecord
elsif !connected?
"#{super} (call '#{super}.connection' to establish a connection)"
elsif table_exists?
- attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
+ attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ', '
"#{super}(#{attr_list})"
else
"#{super}(Table doesn't exist)"
@@ -251,6 +245,12 @@ module ActiveRecord
private
+ def cached_find_by_statement(key, &block) # :nodoc:
+ @find_by_statement_cache[key] || @find_by_statement_cache.synchronize {
+ @find_by_statement_cache[key] ||= StatementCache.create(connection, &block)
+ }
+ end
+
def relation # :nodoc:
relation = Relation.create(self, arel_table, predicate_builder)
@@ -345,9 +345,6 @@ module ActiveRecord
_run_initialize_callbacks
- @aggregation_cache = {}
- @association_cache = {}
-
@new_record = true
@destroyed = false
@@ -456,6 +453,7 @@ module ActiveRecord
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from `pp record`
# when pp is required.
def pretty_print(pp)
+ return super if custom_inspect_method_defined?
pp.object_address_group(self) do
if defined?(@attributes) && @attributes
column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? }
@@ -481,16 +479,16 @@ module ActiveRecord
Hash[methods.map! { |method| [method, public_send(method)] }].with_indifferent_access
end
+ private
+
def set_transaction_state(state) # :nodoc:
@transaction_state = state
end
def has_transactional_callbacks? # :nodoc:
- !_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_create_callbacks.empty?
+ !_rollback_callbacks.empty? || !_commit_callbacks.empty?
end
- private
-
# Updates the attributes on this particular ActiveRecord object so that
# if it is associated with a transaction, then the state of the AR object
# will be updated to reflect the current state of the transaction
@@ -513,6 +511,8 @@ module ActiveRecord
end
def update_attributes_from_transaction_state(transaction_state, depth)
+ @reflects_state = [false] if depth == 0
+
if transaction_state && transaction_state.finalized? && !has_transactional_callbacks?
unless @reflects_state[depth]
restore_transaction_record_state if transaction_state.rolledback?
@@ -539,8 +539,6 @@ module ActiveRecord
end
def init_internals
- @aggregation_cache = {}
- @association_cache = {}
@readonly = false
@destroyed = false
@marked_for_destruction = false
@@ -549,7 +547,6 @@ module ActiveRecord
@txn = nil
@_start_transaction_state = {}
@transaction_state = nil
- @reflects_state = [false]
end
def initialize_internals_callback
@@ -560,5 +557,9 @@ module ActiveRecord
@attributes = @attributes.dup
end
end
+
+ def custom_inspect_method_defined?
+ self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
+ end
end
end