diff options
Diffstat (limited to 'activerecord/lib')
16 files changed, 47 insertions, 27 deletions
diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index 3346725f2d..e3886f394a 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -44,7 +44,7 @@ module ActiveRecord def decrement_counters_before_last_save if reflection.polymorphic? - model_was = owner.attribute_before_last_save(reflection.foreign_type).try(:constantize) + model_was = owner.attribute_before_last_save(reflection.foreign_type)&.constantize else model_was = klass end diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb index fb44232dff..9a4de1a034 100644 --- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb +++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "active_support/core_ext/object/try" + module ActiveRecord module AttributeMethods module TimeZoneConversion diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb index 36001efdd5..276d5a25d4 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -1020,8 +1020,8 @@ module ActiveRecord # In some cases you may want to prevent writes to the database # even if you are on a database that can write. `while_preventing_writes` # will prevent writes to the database for the duration of the block. - def while_preventing_writes - original, @prevent_writes = @prevent_writes, true + def while_preventing_writes(enabled = true) + original, @prevent_writes = @prevent_writes, enabled yield ensure @prevent_writes = original diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index dbd533b4b3..aedd8119ef 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -221,7 +221,7 @@ module ActiveRecord end class_methods do - private def define_column_methods(*column_types) # :nodoc: + def define_column_methods(*column_types) # :nodoc: column_types.each do |column_type| module_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{column_type}(*names, **options) @@ -231,6 +231,7 @@ module ActiveRecord RUBY end end + private :define_column_methods end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb b/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb index 8df91c988b..75213e964b 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb @@ -24,7 +24,7 @@ WARNING: Rails was not able to disable referential integrity. This is most likely caused due to missing permissions. Rails needs superuser privileges to disable referential integrity. - cause: #{original_exception.try(:message)} + cause: #{original_exception&.message} WARNING raise e diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index f33ba87435..d6758c9d4b 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -12,6 +12,7 @@ class ::PG::Connection # :nodoc: end end +require "active_support/core_ext/object/try" require "active_record/connection_adapters/abstract_adapter" require "active_record/connection_adapters/statement_pool" require "active_record/connection_adapters/postgresql/column" diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 595ef4ee25..1b2c9c6754 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -45,7 +45,7 @@ module ActiveRecord # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development", # @spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>, # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production", - # @spec_name="primary", @config={"adapter"=>"mysql2", "database"=>"db/production.sqlite3"}> + # @spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/production.sqlite3"}> # ]> def self.configurations=(config) @@configurations = ActiveRecord::DatabaseConfigurations.new(config) diff --git a/activerecord/lib/active_record/database_configurations.rb b/activerecord/lib/active_record/database_configurations.rb index fcf13a910c..268be34b21 100644 --- a/activerecord/lib/active_record/database_configurations.rb +++ b/activerecord/lib/active_record/database_configurations.rb @@ -9,6 +9,8 @@ module ActiveRecord # objects (either a HashConfig or UrlConfig) that are constructed from the # application's database configuration hash or URL string. class DatabaseConfigurations + class InvalidConfigurationError < StandardError; end + attr_reader :configurations delegate :any?, to: :configurations @@ -146,17 +148,19 @@ module ActiveRecord build_db_config_from_string(env_name, spec_name, config) when Hash build_db_config_from_hash(env_name, spec_name, config.stringify_keys) + else + raise InvalidConfigurationError, "'{ #{env_name} => #{config} }' is not a valid configuration. Expected '#{config}' to be a URL string or a Hash." end end def build_db_config_from_string(env_name, spec_name, config) url = config uri = URI.parse(url) - if uri.try(:scheme) + if uri.scheme ActiveRecord::DatabaseConfigurations::UrlConfig.new(env_name, spec_name, url) + else + raise InvalidConfigurationError, "'{ #{env_name} => #{config} }' is not a valid configuration. Expected '#{config}' to be a URL string or a Hash." end - rescue URI::InvalidURIError - ActiveRecord::DatabaseConfigurations::HashConfig.new(env_name, spec_name, config) end def build_db_config_from_hash(env_name, spec_name, config) diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb index 509f21c9a5..0f110b4536 100644 --- a/activerecord/lib/active_record/errors.rb +++ b/activerecord/lib/active_record/errors.rb @@ -106,7 +106,7 @@ module ActiveRecord # Wraps the underlying database error as +cause+. class StatementInvalid < ActiveRecordError def initialize(message = nil, sql: nil, binds: nil) - super(message || $!.try(:message)) + super(message || $!&.message) @sql = sql @binds = binds end diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index 3df4b3c87f..e4b958f1b9 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -553,15 +553,15 @@ module ActiveRecord end end - def create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base) + def create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base, &block) fixture_set_names = Array(fixture_set_names).map(&:to_s) class_names = ClassCache.new class_names, config # FIXME: Apparently JK uses this. - connection = block_given? ? yield : ActiveRecord::Base.connection + connection = block_given? ? block : lambda { ActiveRecord::Base.connection } fixture_files_to_read = fixture_set_names.reject do |fs_name| - fixture_is_cached?(connection, fs_name) + fixture_is_cached?(connection.call, fs_name) end if fixture_files_to_read.any? @@ -571,9 +571,9 @@ module ActiveRecord class_names, connection, ) - cache_fixtures(connection, fixtures_map) + cache_fixtures(connection.call, fixtures_map) end - cached_fixtures(connection, fixture_set_names) + cached_fixtures(connection.call, fixture_set_names) end # Returns a consistent, platform-independent identifier for +label+. @@ -612,7 +612,11 @@ module ActiveRecord def insert(fixture_sets, connection) # :nodoc: fixture_sets_by_connection = fixture_sets.group_by do |fixture_set| - fixture_set.model_class&.connection || connection + if fixture_set.model_class + fixture_set.model_class.connection + else + connection.call + end end fixture_sets_by_connection.each do |conn, set| @@ -623,6 +627,7 @@ module ActiveRecord table_rows_for_connection[table].unshift(*rows) end end + conn.insert_fixtures_set(table_rows_for_connection, table_rows_for_connection.keys) # Cap primary key sequences to max(pk). diff --git a/activerecord/lib/active_record/insert_all.rb b/activerecord/lib/active_record/insert_all.rb index f6577dcbc4..3863b6bfea 100644 --- a/activerecord/lib/active_record/insert_all.rb +++ b/activerecord/lib/active_record/insert_all.rb @@ -14,7 +14,7 @@ module ActiveRecord @returning = (connection.supports_insert_returning? ? primary_keys : false) if @returning.nil? @returning = false if @returning == [] - @unique_by = find_unique_index_for(unique_by) if unique_by + @unique_by = find_unique_index_for(unique_by || model.primary_key) @on_duplicate = :skip if @on_duplicate == :update && updatable_columns.empty? ensure_valid_options_for_connection! @@ -32,7 +32,7 @@ module ActiveRecord end def primary_keys - Array(model.primary_key) + Array(connection.schema_cache.primary_keys(model.table_name)) end @@ -61,6 +61,8 @@ module ActiveRecord if index = unique_indexes.find { |i| match.include?(i.name) || i.columns == match } index + elsif match == primary_keys + nil else raise ArgumentError, "No unique index found for #{unique_by}" end diff --git a/activerecord/lib/active_record/middleware/database_selector/resolver.rb b/activerecord/lib/active_record/middleware/database_selector/resolver.rb index 3eb1039c50..b2aa453a8e 100644 --- a/activerecord/lib/active_record/middleware/database_selector/resolver.rb +++ b/activerecord/lib/active_record/middleware/database_selector/resolver.rb @@ -46,7 +46,7 @@ module ActiveRecord private def read_from_primary(&blk) ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role) do - ActiveRecord::Base.connection_handler.while_preventing_writes do + ActiveRecord::Base.connection_handler.while_preventing_writes(true) do instrumenter.instrument("database_selector.active_record.read_from_primary") do yield end @@ -64,10 +64,12 @@ module ActiveRecord def write_to_primary(&blk) ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role) do - instrumenter.instrument("database_selector.active_record.wrote_to_primary") do - yield - ensure - context.update_last_write_timestamp + ActiveRecord::Base.connection_handler.while_preventing_writes(false) do + instrumenter.instrument("database_selector.active_record.wrote_to_primary") do + yield + ensure + context.update_last_write_timestamp + end end end end diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb index d5375390c7..f06a98bd98 100644 --- a/activerecord/lib/active_record/railtie.rb +++ b/activerecord/lib/active_record/railtie.rb @@ -2,6 +2,7 @@ require "active_record" require "rails" +require "active_support/core_ext/object/try" require "active_model/railtie" # For now, action_controller must always be present with diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 4d9acc911b..d699e2e21b 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -265,6 +265,8 @@ db_namespace = namespace :db do end abort %{Run `rails db:migrate` to update your database then try again.} end + ensure + ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym) end namespace :abort_if_pending_migrations do diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 29e2e2cedc..2876bae302 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -1114,7 +1114,7 @@ module ActiveRecord else join end - end.compact_blank! + end.compact_blank!.uniq! while joins.first.is_a?(Arel::Nodes::Join) join_node = joins.shift @@ -1144,8 +1144,8 @@ module ActiveRecord def build_join_query(manager, buckets, join_type, aliases) association_joins = buckets[:association_join] stashed_joins = buckets[:stashed_join] - leading_joins = buckets[:leading_join].tap(&:uniq!) - join_nodes = buckets[:join_node].tap(&:uniq!) + leading_joins = buckets[:leading_join] + join_nodes = buckets[:join_node] join_sources = manager.join_sources join_sources.concat(leading_joins) unless leading_joins.empty? diff --git a/activerecord/lib/active_record/serialization.rb b/activerecord/lib/active_record/serialization.rb index 741fea43ce..9fc62a99f8 100644 --- a/activerecord/lib/active_record/serialization.rb +++ b/activerecord/lib/active_record/serialization.rb @@ -11,7 +11,7 @@ module ActiveRecord #:nodoc: end def serializable_hash(options = nil) - options = options.try(:dup) || {} + options = options ? options.dup : {} options[:except] = Array(options[:except]).map(&:to_s) options[:except] |= Array(self.class.inheritance_column) |