aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.rubocop.yml9
-rw-r--r--actionmailer/lib/action_mailer/inline_preview_interceptor.rb4
-rw-r--r--actionpack/lib/action_controller/metal/strong_parameters.rb4
-rw-r--r--actionpack/test/controller/http_digest_authentication_test.rb2
-rw-r--r--actionpack/test/controller/log_subscriber_test.rb4
-rw-r--r--actionpack/test/controller/resources_test.rb4
-rw-r--r--actionpack/test/dispatch/header_test.rb6
-rw-r--r--actionview/test/template/form_helper/form_with_test.rb3
-rw-r--r--actionview/test/template/form_helper_test.rb3
-rw-r--r--activemodel/test/cases/dirty_test.rb16
-rw-r--r--activerecord/lib/active_record/connection_adapters/connection_specification.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb2
-rw-r--r--activerecord/lib/active_record/tasks/mysql_database_tasks.rb4
-rw-r--r--activerecord/lib/active_record/tasks/postgresql_database_tasks.rb4
-rw-r--r--activerecord/lib/active_record/tasks/sqlite_database_tasks.rb8
-rw-r--r--activerecord/test/cases/relation_test.rb2
-rw-r--r--activerecord/test/cases/tasks/database_tasks_test.rb24
-rw-r--r--activestorage/app/jobs/active_storage/purge_job.rb2
-rw-r--r--activestorage/app/models/active_storage/blob.rb1
-rw-r--r--activestorage/test/models/attached/many_test.rb56
-rw-r--r--activestorage/test/models/attached/one_test.rb35
-rw-r--r--activestorage/test/models/blob_test.rb4
-rw-r--r--activesupport/lib/active_support/callbacks.rb6
-rw-r--r--activesupport/lib/active_support/message_encryptor.rb4
-rw-r--r--activesupport/lib/active_support/testing/parallelization.rb16
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb4
-rw-r--r--activesupport/test/cache/stores/redis_cache_store_test.rb4
-rw-r--r--guides/source/active_storage_overview.md8
-rw-r--r--guides/source/form_helpers.md2
-rw-r--r--railties/lib/rails/application.rb8
-rw-r--r--railties/lib/rails/application/configuration.rb4
-rw-r--r--railties/lib/rails/configuration.rb8
-rw-r--r--railties/lib/rails/generators.rb2
-rw-r--r--railties/lib/rails/generators/actions.rb2
-rw-r--r--railties/test/app_loader_test.rb10
-rw-r--r--railties/test/commands/console_test.rb7
37 files changed, 169 insertions, 119 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index 3e3b963a47..d1e8f03f13 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -179,3 +179,12 @@ Style/Semicolon:
# Prefer Foo.method over Foo::method
Style/ColonMethodCall:
Enabled: true
+
+Style/TrivialAccessors:
+ Enabled: true
+
+Performance/FlatMap:
+ Enabled: true
+
+Performance/RedundantMerge:
+ Enabled: true
diff --git a/actionmailer/lib/action_mailer/inline_preview_interceptor.rb b/actionmailer/lib/action_mailer/inline_preview_interceptor.rb
index 8a12f805cc..2b97ac5b94 100644
--- a/actionmailer/lib/action_mailer/inline_preview_interceptor.rb
+++ b/actionmailer/lib/action_mailer/inline_preview_interceptor.rb
@@ -40,9 +40,7 @@ module ActionMailer
end
private
- def message
- @message
- end
+ attr_reader :message
def html_part
@html_part ||= message.html_part
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb
index a6f395d33b..7af29f8dca 100644
--- a/actionpack/lib/action_controller/metal/strong_parameters.rb
+++ b/actionpack/lib/action_controller/metal/strong_parameters.rb
@@ -793,9 +793,7 @@ module ActionController
protected
attr_reader :parameters
- def permitted=(new_permitted)
- @permitted = new_permitted
- end
+ attr_writer :permitted
def fields_for_style?
@parameters.all? { |k, v| k =~ /\A-?\d+\z/ && (v.is_a?(Hash) || v.is_a?(Parameters)) }
diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb
index 3f211cd60d..b133afb343 100644
--- a/actionpack/test/controller/http_digest_authentication_test.rb
+++ b/actionpack/test/controller/http_digest_authentication_test.rb
@@ -272,7 +272,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
credentials.merge!(options)
path_info = @request.env["PATH_INFO"].to_s
uri = options[:uri] || path_info
- credentials.merge!(uri: uri)
+ credentials[:uri] = uri
@request.env["ORIGINAL_FULLPATH"] = path_info
ActionController::HttpAuthentication::Digest.encode_credentials(method, credentials, password, options[:password_is_ha1])
end
diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb
index be455642de..0562c16284 100644
--- a/actionpack/test/controller/log_subscriber_test.rb
+++ b/actionpack/test/controller/log_subscriber_test.rb
@@ -82,9 +82,7 @@ module Another
@last_payload = payload
end
- def last_payload
- @last_payload
- end
+ attr_reader :last_payload
end
end
diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb
index 3688fdbeee..d336b96eff 100644
--- a/actionpack/test/controller/resources_test.rb
+++ b/actionpack/test/controller/resources_test.rb
@@ -1322,7 +1322,7 @@ class ResourcesTest < ActionController::TestCase
def assert_resource_allowed_routes(controller, options, shallow_options, allowed, not_allowed, path = controller)
shallow_path = "#{path}/#{shallow_options[:id]}"
format = options[:format] && ".#{options[:format]}"
- options.merge!(controller: controller)
+ options[:controller] = controller
shallow_options.merge!(options)
assert_whether_allowed(allowed, not_allowed, options, "index", "#{path}#{format}", :get)
@@ -1336,7 +1336,7 @@ class ResourcesTest < ActionController::TestCase
def assert_singleton_resource_allowed_routes(controller, options, allowed, not_allowed, path = controller.singularize)
format = options[:format] && ".#{options[:format]}"
- options.merge!(controller: controller)
+ options[:controller] = controller
assert_whether_allowed(allowed, not_allowed, options, "new", "#{path}/new#{format}", :get)
assert_whether_allowed(allowed, not_allowed, options, "create", "#{path}#{format}", :post)
diff --git a/actionpack/test/dispatch/header_test.rb b/actionpack/test/dispatch/header_test.rb
index 3a265a056b..43e63eb996 100644
--- a/actionpack/test/dispatch/header_test.rb
+++ b/actionpack/test/dispatch/header_test.rb
@@ -105,16 +105,20 @@ class HeaderTest < ActiveSupport::TestCase
end
test "#merge! headers with mutation" do
+ # rubocop:disable Performance/RedundantMerge
@headers.merge!("Host" => "http://example.test",
"Content-Type" => "text/html")
+ # rubocop:enable Performance/RedundantMerge
assert_equal({ "HTTP_HOST" => "http://example.test",
"CONTENT_TYPE" => "text/html",
"HTTP_REFERER" => "/some/page" }, @headers.env)
end
test "#merge! env with mutation" do
+ # rubocop:disable Performance/RedundantMerge
@headers.merge!("HTTP_HOST" => "http://first.com",
"CONTENT_TYPE" => "text/html")
+ # rubocop:enable Performance/RedundantMerge
assert_equal({ "HTTP_HOST" => "http://first.com",
"CONTENT_TYPE" => "text/html",
"HTTP_REFERER" => "/some/page" }, @headers.env)
@@ -156,7 +160,7 @@ class HeaderTest < ActiveSupport::TestCase
env = { "HTTP_REFERER" => "/" }
headers = make_headers(env)
headers["Referer"] = "http://example.com/"
- headers.merge! "CONTENT_TYPE" => "text/plain"
+ headers["CONTENT_TYPE"] = "text/plain"
assert_equal({ "HTTP_REFERER" => "http://example.com/",
"CONTENT_TYPE" => "text/plain" }, env)
end
diff --git a/actionview/test/template/form_helper/form_with_test.rb b/actionview/test/template/form_helper/form_with_test.rb
index f07e494ee3..c30176349c 100644
--- a/actionview/test/template/form_helper/form_with_test.rb
+++ b/actionview/test/template/form_helper/form_with_test.rb
@@ -318,7 +318,8 @@ class FormWithActsLikeFormForTest < FormWithTest
@url_for_options = object
if object.is_a?(Hash) && object[:use_route].blank? && object[:controller].blank?
- object.merge!(controller: "main", action: "index")
+ object[:controller] = "main"
+ object[:action] = "index"
end
super
diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb
index 5244204e42..38bb1e1d24 100644
--- a/actionview/test/template/form_helper_test.rb
+++ b/actionview/test/template/form_helper_test.rb
@@ -168,7 +168,8 @@ class FormHelperTest < ActionView::TestCase
@url_for_options = object
if object.is_a?(Hash) && object[:use_route].blank? && object[:controller].blank?
- object.merge!(controller: "main", action: "index")
+ object[:controller] = "main"
+ object[:action] = "index"
end
super
diff --git a/activemodel/test/cases/dirty_test.rb b/activemodel/test/cases/dirty_test.rb
index b120e68027..b38d84fff2 100644
--- a/activemodel/test/cases/dirty_test.rb
+++ b/activemodel/test/cases/dirty_test.rb
@@ -14,37 +14,23 @@ class DirtyTest < ActiveModel::TestCase
@status = "initialized"
end
- def name
- @name
- end
+ attr_reader :name, :color, :size, :status
def name=(val)
name_will_change!
@name = val
end
- def color
- @color
- end
-
def color=(val)
color_will_change! unless val == @color
@color = val
end
- def size
- @size
- end
-
def size=(val)
attribute_will_change!(:size) unless val == @size
@size = val
end
- def status
- @status
- end
-
def status=(val)
status_will_change! unless val == @status
@status = val
diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb
index 901717ae3d..204691006c 100644
--- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb
+++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb
@@ -57,9 +57,7 @@ module ActiveRecord
private
- def uri
- @uri
- end
+ attr_reader :uri
def uri_parser
@uri_parser ||= URI::Parser.new
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb
index 2087938d7c..1cf210d85b 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb
@@ -36,7 +36,7 @@ module ActiveRecord
end
indexes.last[-2] << row[:Column_name]
- indexes.last[-1][:lengths].merge!(row[:Column_name] => row[:Sub_part].to_i) if row[:Sub_part]
+ indexes.last[-1][:lengths][row[:Column_name]] = row[:Sub_part].to_i if row[:Sub_part]
indexes.last[-1][:orders].merge!(row[:Column_name] => :desc) if row[:Collation] == "D"
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index 4c57bd48ab..544d720428 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -117,7 +117,7 @@ module ActiveRecord
end
def configure_connection
- @connection.query_options.merge!(as: :array)
+ @connection.query_options[:as] = :array
super
end
diff --git a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb
index e697fa6def..eddc6fa223 100644
--- a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb
+++ b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb
@@ -68,9 +68,7 @@ module ActiveRecord
private
- def configuration
- @configuration
- end
+ attr_reader :configuration
def configuration_without_database
configuration.merge("database" => nil)
diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb
index 647e066137..533e6953a4 100644
--- a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb
+++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb
@@ -90,9 +90,7 @@ module ActiveRecord
private
- def configuration
- @configuration
- end
+ attr_reader :configuration
def encoding
configuration["encoding"] || DEFAULT_ENCODING
diff --git a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb
index dfe599c4dd..d0bad05176 100644
--- a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb
+++ b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb
@@ -60,13 +60,7 @@ module ActiveRecord
private
- def configuration
- @configuration
- end
-
- def root
- @root
- end
+ attr_reader :configuration, :root
def run_cmd(cmd, args, out)
fail run_cmd_error(cmd, args) unless Kernel.system(cmd, *args, out: out)
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb
index fbeb617b29..3ca15640fd 100644
--- a/activerecord/test/cases/relation_test.rb
+++ b/activerecord/test/cases/relation_test.rb
@@ -187,7 +187,7 @@ module ActiveRecord
end
relation = Relation.new(klass)
- relation.merge!(where: ["foo = ?", "bar"])
+ relation.merge!(where: ["foo = ?", "bar"]) # rubocop:disable Performance/RedundantMerge
assert_equal Relation::WhereClause.new(["foo = bar"]), relation.where_clause
end
diff --git a/activerecord/test/cases/tasks/database_tasks_test.rb b/activerecord/test/cases/tasks/database_tasks_test.rb
index b9cc08c446..a6efe3fa5e 100644
--- a/activerecord/test/cases/tasks/database_tasks_test.rb
+++ b/activerecord/test/cases/tasks/database_tasks_test.rb
@@ -152,7 +152,7 @@ module ActiveRecord
end
def test_ignores_configurations_without_databases
- @configurations["development"].merge!("database" => nil)
+ @configurations["development"]["database"] = nil
with_stubbed_configurations_establish_connection do
assert_not_called(ActiveRecord::Tasks::DatabaseTasks, :create) do
@@ -162,7 +162,7 @@ module ActiveRecord
end
def test_ignores_remote_databases
- @configurations["development"].merge!("host" => "my.server.tld")
+ @configurations["development"]["host"] = "my.server.tld"
with_stubbed_configurations_establish_connection do
assert_not_called(ActiveRecord::Tasks::DatabaseTasks, :create) do
@@ -172,7 +172,7 @@ module ActiveRecord
end
def test_warning_for_remote_databases
- @configurations["development"].merge!("host" => "my.server.tld")
+ @configurations["development"]["host"] = "my.server.tld"
with_stubbed_configurations_establish_connection do
ActiveRecord::Tasks::DatabaseTasks.create_all
@@ -183,7 +183,7 @@ module ActiveRecord
end
def test_creates_configurations_with_local_ip
- @configurations["development"].merge!("host" => "127.0.0.1")
+ @configurations["development"]["host"] = "127.0.0.1"
with_stubbed_configurations_establish_connection do
assert_called(ActiveRecord::Tasks::DatabaseTasks, :create) do
@@ -193,7 +193,7 @@ module ActiveRecord
end
def test_creates_configurations_with_local_host
- @configurations["development"].merge!("host" => "localhost")
+ @configurations["development"]["host"] = "localhost"
with_stubbed_configurations_establish_connection do
assert_called(ActiveRecord::Tasks::DatabaseTasks, :create) do
@@ -203,7 +203,7 @@ module ActiveRecord
end
def test_creates_configurations_with_blank_hosts
- @configurations["development"].merge!("host" => nil)
+ @configurations["development"]["host"] = nil
with_stubbed_configurations_establish_connection do
assert_called(ActiveRecord::Tasks::DatabaseTasks, :create) do
@@ -463,7 +463,7 @@ module ActiveRecord
end
def test_ignores_configurations_without_databases
- @configurations[:development].merge!("database" => nil)
+ @configurations[:development]["database"] = nil
ActiveRecord::Base.stub(:configurations, @configurations) do
assert_not_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
@@ -473,7 +473,7 @@ module ActiveRecord
end
def test_ignores_remote_databases
- @configurations[:development].merge!("host" => "my.server.tld")
+ @configurations[:development]["host"] = "my.server.tld"
ActiveRecord::Base.stub(:configurations, @configurations) do
assert_not_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
@@ -483,7 +483,7 @@ module ActiveRecord
end
def test_warning_for_remote_databases
- @configurations[:development].merge!("host" => "my.server.tld")
+ @configurations[:development]["host"] = "my.server.tld"
ActiveRecord::Base.stub(:configurations, @configurations) do
ActiveRecord::Tasks::DatabaseTasks.drop_all
@@ -494,7 +494,7 @@ module ActiveRecord
end
def test_drops_configurations_with_local_ip
- @configurations[:development].merge!("host" => "127.0.0.1")
+ @configurations[:development]["host"] = "127.0.0.1"
ActiveRecord::Base.stub(:configurations, @configurations) do
assert_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
@@ -504,7 +504,7 @@ module ActiveRecord
end
def test_drops_configurations_with_local_host
- @configurations[:development].merge!("host" => "localhost")
+ @configurations[:development]["host"] = "localhost"
ActiveRecord::Base.stub(:configurations, @configurations) do
assert_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
@@ -514,7 +514,7 @@ module ActiveRecord
end
def test_drops_configurations_with_blank_hosts
- @configurations[:development].merge!("host" => nil)
+ @configurations[:development]["host"] = nil
ActiveRecord::Base.stub(:configurations, @configurations) do
assert_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
diff --git a/activestorage/app/jobs/active_storage/purge_job.rb b/activestorage/app/jobs/active_storage/purge_job.rb
index b021b5f2d0..fa15e0451d 100644
--- a/activestorage/app/jobs/active_storage/purge_job.rb
+++ b/activestorage/app/jobs/active_storage/purge_job.rb
@@ -2,7 +2,7 @@
# Provides asynchronous purging of ActiveStorage::Blob records via ActiveStorage::Blob#purge_later.
class ActiveStorage::PurgeJob < ActiveStorage::BaseJob
- discard_on ActiveRecord::RecordNotFound, ActiveRecord::InvalidForeignKey
+ discard_on ActiveRecord::RecordNotFound
def perform(blob)
blob.purge
diff --git a/activestorage/app/models/active_storage/blob.rb b/activestorage/app/models/active_storage/blob.rb
index bf87598a66..e7f2615b0f 100644
--- a/activestorage/app/models/active_storage/blob.rb
+++ b/activestorage/app/models/active_storage/blob.rb
@@ -207,6 +207,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
def purge
destroy
delete
+ rescue ActiveRecord::InvalidForeignKey
end
# Enqueues an ActiveStorage::PurgeJob to call #purge. This is the recommended way to purge blobs from a transaction,
diff --git a/activestorage/test/models/attached/many_test.rb b/activestorage/test/models/attached/many_test.rb
index 334254d099..3b563b3fc8 100644
--- a/activestorage/test/models/attached/many_test.rb
+++ b/activestorage/test/models/attached/many_test.rb
@@ -468,6 +468,33 @@ class ActiveStorage::ManyAttachedTest < ActiveSupport::TestCase
end
end
+ test "purging attachment with shared blobs" do
+ [
+ create_blob(filename: "funky.jpg"),
+ create_blob(filename: "town.jpg"),
+ create_blob(filename: "worm.jpg")
+ ].tap do |blobs|
+ @user.highlights.attach blobs
+ assert @user.highlights.attached?
+
+ another_user = User.create!(name: "John")
+ shared_blobs = [blobs.second, blobs.third]
+ another_user.highlights.attach shared_blobs
+ assert another_user.highlights.attached?
+
+ @user.highlights.purge
+ assert_not @user.highlights.attached?
+
+ assert_not ActiveStorage::Blob.exists?(blobs.first.id)
+ assert ActiveStorage::Blob.exists?(blobs.second.id)
+ assert ActiveStorage::Blob.exists?(blobs.third.id)
+
+ assert_not ActiveStorage::Blob.service.exist?(blobs.first.key)
+ assert ActiveStorage::Blob.service.exist?(blobs.second.key)
+ assert ActiveStorage::Blob.service.exist?(blobs.third.key)
+ end
+ end
+
test "purging later" do
[ create_blob(filename: "funky.jpg"), create_blob(filename: "town.jpg") ].tap do |blobs|
@user.highlights.attach blobs
@@ -485,6 +512,35 @@ class ActiveStorage::ManyAttachedTest < ActiveSupport::TestCase
end
end
+ test "purging attachment later with shared blobs" do
+ [
+ create_blob(filename: "funky.jpg"),
+ create_blob(filename: "town.jpg"),
+ create_blob(filename: "worm.jpg")
+ ].tap do |blobs|
+ @user.highlights.attach blobs
+ assert @user.highlights.attached?
+
+ another_user = User.create!(name: "John")
+ shared_blobs = [blobs.second, blobs.third]
+ another_user.highlights.attach shared_blobs
+ assert another_user.highlights.attached?
+
+ perform_enqueued_jobs do
+ @user.highlights.purge_later
+ end
+
+ assert_not @user.highlights.attached?
+ assert_not ActiveStorage::Blob.exists?(blobs.first.id)
+ assert ActiveStorage::Blob.exists?(blobs.second.id)
+ assert ActiveStorage::Blob.exists?(blobs.third.id)
+
+ assert_not ActiveStorage::Blob.service.exist?(blobs.first.key)
+ assert ActiveStorage::Blob.service.exist?(blobs.second.key)
+ assert ActiveStorage::Blob.service.exist?(blobs.third.key)
+ end
+ end
+
test "purging dependent attachment later on destroy" do
[ create_blob(filename: "funky.jpg"), create_blob(filename: "town.jpg") ].tap do |blobs|
@user.highlights.attach blobs
diff --git a/activestorage/test/models/attached/one_test.rb b/activestorage/test/models/attached/one_test.rb
index 3333fd9323..561c3e9d23 100644
--- a/activestorage/test/models/attached/one_test.rb
+++ b/activestorage/test/models/attached/one_test.rb
@@ -412,6 +412,22 @@ class ActiveStorage::OneAttachedTest < ActiveSupport::TestCase
end
end
+ test "purging an attachment with a shared blob" do
+ create_blob(filename: "funky.jpg").tap do |blob|
+ @user.avatar.attach blob
+ assert @user.avatar.attached?
+
+ another_user = User.create!(name: "John")
+ another_user.avatar.attach blob
+ assert another_user.avatar.attached?
+
+ @user.avatar.purge
+ assert_not @user.avatar.attached?
+ assert ActiveStorage::Blob.exists?(blob.id)
+ assert ActiveStorage::Blob.service.exist?(blob.key)
+ end
+ end
+
test "purging later" do
create_blob(filename: "funky.jpg").tap do |blob|
@user.avatar.attach blob
@@ -427,6 +443,25 @@ class ActiveStorage::OneAttachedTest < ActiveSupport::TestCase
end
end
+ test "purging an attachment later with shared blob" do
+ create_blob(filename: "funky.jpg").tap do |blob|
+ @user.avatar.attach blob
+ assert @user.avatar.attached?
+
+ another_user = User.create!(name: "John")
+ another_user.avatar.attach blob
+ assert another_user.avatar.attached?
+
+ perform_enqueued_jobs do
+ @user.avatar.purge_later
+ end
+
+ assert_not @user.avatar.attached?
+ assert ActiveStorage::Blob.exists?(blob.id)
+ assert ActiveStorage::Blob.service.exist?(blob.key)
+ end
+ end
+
test "purging dependent attachment later on destroy" do
create_blob(filename: "funky.jpg").tap do |blob|
@user.avatar.attach blob
diff --git a/activestorage/test/models/blob_test.rb b/activestorage/test/models/blob_test.rb
index c2e7aae13a..88c106a08b 100644
--- a/activestorage/test/models/blob_test.rb
+++ b/activestorage/test/models/blob_test.rb
@@ -174,10 +174,10 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase
assert_not ActiveStorage::Blob.service.exist?(variant.key)
end
- test "purge fails when attachments exist" do
+ test "purge does nothing when attachments exist" do
create_blob.tap do |blob|
User.create! name: "DHH", avatar: blob
- assert_raises(ActiveRecord::InvalidForeignKey) { blob.purge }
+ assert_no_difference(-> { ActiveStorage::Blob.count }) { blob.purge }
assert ActiveStorage::Blob.service.exist?(blob.key)
end
end
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index a1b841ec3d..c266b432c0 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -497,9 +497,7 @@ module ActiveSupport
arg.halted || !@user_conditions.all? { |c| c.call(arg.target, arg.value) }
end
- def nested
- @nested
- end
+ attr_reader :nested
def final?
!@call_template
@@ -578,7 +576,7 @@ module ActiveSupport
end
protected
- def chain; @chain; end
+ attr_reader :chain
private
diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb
index 8b73270894..404404cad1 100644
--- a/activesupport/lib/active_support/message_encryptor.rb
+++ b/activesupport/lib/active_support/message_encryptor.rb
@@ -210,9 +210,7 @@ module ActiveSupport
OpenSSL::Cipher.new(@cipher)
end
- def verifier
- @verifier
- end
+ attr_reader :verifier
def aead_mode?
@aead_mode ||= new_cipher.authenticated?
diff --git a/activesupport/lib/active_support/testing/parallelization.rb b/activesupport/lib/active_support/testing/parallelization.rb
index 59c8486f41..1caac1feb3 100644
--- a/activesupport/lib/active_support/testing/parallelization.rb
+++ b/activesupport/lib/active_support/testing/parallelization.rb
@@ -26,25 +26,21 @@ module ActiveSupport
def pop; @queue.pop; end
end
- @after_fork_hooks = []
+ @@after_fork_hooks = []
def self.after_fork_hook(&blk)
- @after_fork_hooks << blk
+ @@after_fork_hooks << blk
end
- def self.after_fork_hooks
- @after_fork_hooks
- end
+ cattr_reader :after_fork_hooks
- @run_cleanup_hooks = []
+ @@run_cleanup_hooks = []
def self.run_cleanup_hook(&blk)
- @run_cleanup_hooks << blk
+ @@run_cleanup_hooks << blk
end
- def self.run_cleanup_hooks
- @run_cleanup_hooks
- end
+ cattr_reader :run_cleanup_hooks
def initialize(queue_size)
@queue_size = queue_size
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 792c88415c..fd07a3a6a2 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -265,7 +265,7 @@ module ActiveSupport
private
def load_country_zones(code)
country = TZInfo::Country.get(code)
- country.zone_identifiers.map do |tz_id|
+ country.zone_identifiers.flat_map do |tz_id|
if MAPPING.value?(tz_id)
MAPPING.inject([]) do |memo, (key, value)|
memo << self[key] if value == tz_id
@@ -274,7 +274,7 @@ module ActiveSupport
else
create(tz_id, nil, TZInfo::Timezone.new(tz_id))
end
- end.flatten(1).sort!
+ end.sort!
end
def zones_map
diff --git a/activesupport/test/cache/stores/redis_cache_store_test.rb b/activesupport/test/cache/stores/redis_cache_store_test.rb
index 3b873de383..305a2c184d 100644
--- a/activesupport/test/cache/stores/redis_cache_store_test.rb
+++ b/activesupport/test/cache/stores/redis_cache_store_test.rb
@@ -103,9 +103,7 @@ module ActiveSupport::Cache::RedisCacheStoreTests
private
def build(**kwargs)
- ActiveSupport::Cache::RedisCacheStore.new(driver: DRIVER, **kwargs).tap do |cache|
- cache.redis
- end
+ ActiveSupport::Cache::RedisCacheStore.new(driver: DRIVER, **kwargs).tap(&:redis)
end
end
diff --git a/guides/source/active_storage_overview.md b/guides/source/active_storage_overview.md
index 182d784595..6933717c2b 100644
--- a/guides/source/active_storage_overview.md
+++ b/guides/source/active_storage_overview.md
@@ -36,10 +36,10 @@ files.
## Setup
Active Storage uses two tables in your application’s database named
-`active_storage_blobs` and `active_storage_attachments`. After upgrading your
-application to Rails 5.2, run `rails active_storage:install` to generate a
-migration that creates these tables. Use `rails db:migrate` to run the
-migration.
+`active_storage_blobs` and `active_storage_attachments`. After creating a new
+application (or upgrading your application to Rails 5.2), run
+`rails active_storage:install` to generate a migration that creates these
+tables. Use `rails db:migrate` to run the migration.
Declare Active Storage services in `config/storage.yml`. For each service your
application uses, provide a name and the requisite configuration. The example
diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md
index e1dbe39137..a4f7e6f601 100644
--- a/guides/source/form_helpers.md
+++ b/guides/source/form_helpers.md
@@ -651,7 +651,7 @@ def upload
end
```
-Once a file has been uploaded, there are a multitude of potential tasks, ranging from where to store the files (on disk, Amazon S3, etc) and associating them with models to resizing image files and generating thumbnails. The intricacies of this are beyond the scope of this guide, but there are several libraries designed to assist with these. Two of the better known ones are [CarrierWave](https://github.com/jnicklas/carrierwave) and [Paperclip](https://github.com/thoughtbot/paperclip).
+Once a file has been uploaded, there are a multitude of potential tasks, ranging from where to store the files (on disk, Amazon S3, etc) and associating them with models to resizing image files and generating thumbnails. [Active Storage](https://guides.rubyonrails.org/active_storage_overview.html) is designed to assist with these tasks.
NOTE: If the user has not selected a file the corresponding parameter will be an empty string.
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 76a8ccb8f1..31d0d65a30 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -373,9 +373,7 @@ module Rails
@config ||= Application::Configuration.new(self.class.find_root(self.class.called_from))
end
- def config=(configuration) #:nodoc:
- @config = configuration
- end
+ attr_writer :config
# Returns secrets added to config/secrets.yml.
#
@@ -413,9 +411,7 @@ module Rails
end
end
- def secrets=(secrets) #:nodoc:
- @secrets = secrets
- end
+ attr_writer :secrets
# The secret_key_base is used as the input secret to the application's key generator, which in turn
# is used to create all MessageVerifiers/MessageEncryptors, including the ones that sign and encrypt cookies.
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index bba573499d..9c54cc1f37 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -146,9 +146,7 @@ module Rails
@debug_exception_response_format || :default
end
- def debug_exception_response_format=(value)
- @debug_exception_response_format = value
- end
+ attr_writer :debug_exception_response_format
def paths
@paths ||= begin
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb
index d3a54d9364..e8741a50ba 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -79,13 +79,7 @@ module Rails
end
protected
- def operations
- @operations
- end
-
- def delete_operations
- @delete_operations
- end
+ attr_reader :operations, :delete_operations
end
class Generators #:nodoc:
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 2a41403557..ed672ae48e 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -126,7 +126,7 @@ module Rails
)
if ARGV.first == "mailer"
- options[:rails].merge!(template_engine: :erb)
+ options[:rails][:template_engine] = :erb
end
end
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index d85bbfb03e..ae395708cb 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -298,7 +298,7 @@ module Rails
sudo = options[:sudo] && !Gem.win_platform? ? "sudo " : ""
config = { verbose: false }
- config.merge!(capture: options[:capture]) if options[:capture]
+ config[:capture] = options[:capture] if options[:capture]
in_root { run("#{sudo}#{extify(executor)} #{command} RAILS_ENV=#{env}", config) }
end
diff --git a/railties/test/app_loader_test.rb b/railties/test/app_loader_test.rb
index 93ed68fabb..0deb1a76df 100644
--- a/railties/test/app_loader_test.rb
+++ b/railties/test/app_loader_test.rb
@@ -9,12 +9,12 @@ class AppLoaderTest < ActiveSupport::TestCase
@loader ||= Class.new do
extend Rails::AppLoader
- def self.exec_arguments
- @exec_arguments
- end
+ class << self
+ attr_accessor :exec_arguments
- def self.exec(*args)
- @exec_arguments = args
+ def exec(*args)
+ self.exec_arguments = args
+ end
end
end
end
diff --git a/railties/test/commands/console_test.rb b/railties/test/commands/console_test.rb
index b7cdb8229e..0b2fe204f8 100644
--- a/railties/test/commands/console_test.rb
+++ b/railties/test/commands/console_test.rb
@@ -151,7 +151,8 @@ class Rails::ConsoleTest < ActiveSupport::TestCase
def build_app(console)
mocked_console = Class.new do
- attr_reader :sandbox, :console
+ attr_accessor :sandbox
+ attr_reader :console
def initialize(console)
@console = console
@@ -161,10 +162,6 @@ class Rails::ConsoleTest < ActiveSupport::TestCase
self
end
- def sandbox=(arg)
- @sandbox = arg
- end
-
def load_console
end
end