Upgrading activestorage 7 to 8
Breaking7.2.4 → 8.1.4Breaking49Security21Platform1Deprecated24New230Changed182Fixed372Other8
SecurityLimits the size of strings ActiveModel::Type::Integer coerces with to_i to avoid a DoS vector from very long strings.Advisory ↗
BreakingUpgrade verdict
49 breaking changes and a platform requirement change and 21 security fixes.
In plain terms
- Code that passed a Time object to Time#since no longer works and must be updated.
- Benchmark.ms is no longer part of Active Support; use the benchmark gem instead.
- Adding a Time and an ActiveSupport::TimeWithZone no longer works as before.
- to_time now always keeps the receiver's timezone instead of optionally using the system local time.
Must act Top 5 of 93 that need code or config changes
Ruby requirement changed in 8.0.0.beta1: >= 3.1.0 → >= 3.2.0.
What you must change
Breaking49
Removes deprecated support for passing a Time object to Time#since.
Time#sinceRemoves the deprecated Benchmark.ms method, now defined in the benchmark gem.
Benchmark.msRemoves deprecated addition of Time instances with ActiveSupport::TimeWithZone.
TimeActiveSupport::TimeWithZoneRemoves deprecated support for to_time preserving the system local time; it now always preserves the receiver timezone.
to_timeRemoves deprecated :unsigned_float and :unsigned_decimal column methods for MySQL.
:unsigned_float:unsigned_decimalRemoves deprecated :retries option for the SQLite3 adapter.
:retriesRemoves deprecated support to route to multiple paths.
Removes deprecated support for using semicolons as a query string separator.
ActionDispatch::QueryParser.each_pairRemoves deprecated support for skipping over leading brackets in parameter names in the parameter parser.
ActionDispatch::ParamBuilder.from_query_stringThe JSON renderer no longer escapes HTML entities or Unicode line separators by default; use escape: true or config.action_controller.escape_json_responses to restore.
render json:escapeconfig.action_controller.escape_json_responsescallbackRemoves support for setting ActiveJob::Base.enqueue_after_transaction_commit to :never, :always and :default.
ActiveJob::Base.enqueue_after_transaction_commitRemoves deprecated Rails.application.config.active_job.enqueue_after_transaction_commit.
Rails.application.config.active_job.enqueue_after_transaction_commitRemoves the deprecated :azure storage service.
:azureRemoves deprecated STATS_DIRECTORIES.
STATS_DIRECTORIESRemoves the deprecated bin/rake stats command.
bin/rake statsRemoves the deprecated rails/console/methods.rb file.
rails/console/methods.rbRemoves deprecated support for passing an array of strings to ActiveSupport::Deprecation#warn.
ActiveSupport::Deprecation#warnRemoves deprecated support for setting attr_internal_naming_format with a @ prefix.
attr_internal_naming_formatRemoves the deprecated ActiveSupport::ProxyObject.
ActiveSupport::ProxyObjectRemoves deprecated support for setting ENV["SCHEMA_CACHE"].
ENV["SCHEMA_CACHE"]Removes deprecated support for passing a database name to cache_dump_filename.
cache_dump_filenameRemoves deprecated ActiveRecord::ConnectionAdapters::ConnectionPool#connection.
ActiveRecord::ConnectionAdapters::ConnectionPool#connectionRemoves deprecated config.active_record.sqlite3_deprecated_warning.
config.active_record.sqlite3_deprecated_warningRemoves deprecated config.active_record.warn_on_records_fetched_greater_than.
config.active_record.warn_on_records_fetched_greater_thanRemoves deprecated support for defining enum with keyword arguments.
enumRemoves deprecated support for finding database adapters that are not registered to Active Record.
Removes deprecated config.active_record.allow_deprecated_singular_associations_name.
config.active_record.allow_deprecated_singular_associations_nameRemoves deprecated
config.active_record.commit_transaction_on_non_local_return.config.active_record.commit_transaction_on_non_local_returnDeletes the deprecated constant ActiveRecord::ImmutableRelation.
ActiveRecord::ImmutableRelationRemoves deprecated support for passing content to void tag elements on the tag builder.
tagRemoves deprecated support for passing nil to the model: argument of form_with.
form_withRemoves Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality.
Rails.application.config.action_controller.allow_deprecated_parameters_hash_equalityRemoves deprecated
config.active_job.use_big_decimal_serializer.config.active_job.use_big_decimal_serializerRemoves deprecated support for extending the Rails console through Rails::ConsoleMethods.
Rails::ConsoleMethodsRemoves the deprecated file rails/console/helpers.
rails/console/helpersRemoves the deprecated file rails/console/app.
rails/console/appRemoves deprecated config.read_encrypted_secrets.
config.read_encrypted_secretsAlways clears CurrentAttributes instances, abandoning them at request end and creating a new instance on the next request.
CurrentAttributesMakes :class_name invalid in polymorphic belongs_to associations.
class_namebelongs_toRaises AbstractController::DoubleRenderError when head is called after rendering.
AbstractController::DoubleRenderErrorheadA route pointing to a non-existing controller now returns 500 instead of 404.
Removes the deprecated internal SuckerPunch adapter in favor of the adapter included with the sucker_punch gem.
SuckerPunchAlways clears CurrentAttributes instances by abandoning them at request end and creating a new instance at the next request start.
CurrentAttributesMakes :class_name invalid in polymorphic belongs_to associations.
belongs_toclass_nameRaises AbstractController::DoubleRenderError when head is called after rendering.
headAbstractController::DoubleRenderErrorA route pointing to a non-existing controller now returns 500 instead of 404.
:controllerRemoves the deprecated internal SuckerPunch adapter in favor of the adapter included with the sucker_punch gem.
SuckerPunchsucker_punchFixes ActiveSupport::HashWithIndifferentAccess#stringify_keys to stringify all keys, not just symbols.
ActiveSupport::HashWithIndifferentAccess#stringify_keysRaises when EncryptedConfiguration is given a key that cannot respond to #to_sym, such as an Integer or Float.
EncryptedConfiguration#to_symSecurity21
Limits the size of strings ActiveModel::Type::Integer coerces with to_i to avoid a DoS vector from very long strings.
ActiveModel::Type::Integerto_iFilters the database password out of failed db: task command error messages.
Rejects malformed hosts with extra ports in
ActionDispatch::HostAuthorization.ActionDispatch::HostAuthorizationFixes possible XSS in DebugExceptions middleware.
DebugExceptionsFilters attributes listed in filter_attributes also through filter_parameters to avoid leaking sensitive information.
filter_attributesfilter_parametersRate limits password resets in the authentication generator to mitigate abuse from attackers spamming the password reset form.
Rate limits password resets in the authentication generator to mitigate abuse from spamming the password reset form.
Disables libvips unfuzzed image loaders and savers via Vips.block_untrusted(true) at boot, and raises RuntimeError if libvips < 8.13 or ruby-vips < 2.2.1.
Vips.block_untrusted(true)Vips::Errorconfig.active_storage.variable_content_types:mini_magickCriticalRejects scientific notation in NumberConverter.
NumberConverterFixes SafeBuffer#% to preserve unsafe status.
SafeBuffer#%Improves performance of NumberToDelimitedConverter.
NumberToDelimitedConverterSkips blank attribute names in tag helpers to avoid generating invalid HTML.
Filters user supplied metadata in DirectUploadController.
DirectUploadControllerModerateAdds a configurable maximum streaming chunk size, defaulting to 100mb byte ranges for blobs.
ModerateLimits range requests to a single range.
Low · CVSS 6.5Prevents path traversal in DiskService; path_for raises InvalidKeyError for dot segments or paths outside the storage root.
DiskServiceDiskService#path_forInvalidKeyErrorDiskControllerHighPrevents glob injection in DiskService#delete_prefixed by escaping glob metacharacters, breaking code that relied on glob expansion.
DiskService#delete_prefixedDir.globModerateCalls inspect on ids in RecordNotFound error to address CVE-2025-55193.
RecordNotFoundRemoves dangerous transformations to address CVE-2025-24293.
CriticalAdds validation to content security policies to disallow spaces and semicolons.
Sets Regexp.timeout to 1 second by default to improve security against Regexp Denial-of-Service attacks.
Regexp.timeoutPlatform1
Raises minimum supported libvips to 8.13 and ruby-vips to 2.2.1, raising RuntimeError at boot when ruby-vips is installed and either minimum is unmet.
RuntimeErrorDeprecations to plan for
Deprecated22
Deprecates config.active_support.to_time_preserves_timezone.
config.active_support.to_time_preserves_timezoneDeprecates String#mb_chars and ActiveSupport::Multibyte::Chars.
String#mb_charsActiveSupport::Multibyte::CharsDeprecates ActiveSupport::Configurable.
ActiveSupport::ConfigurableDeprecates using
insert_all/upsert_all with unpersisted records in associations.insert_allupsert_allDeprecates using
update_all with WITH, WITH RECURSIVE or DISTINCT statements, which were ignored; an error will be raised in a future release.update_alldelete_allDeprecates
Rails.application.config.action_dispatch.ignore_leading_brackets.Rails.application.config.action_dispatch.ignore_leading_bracketsDeprecates the built-in sidekiq adapter; use sidekiq 7.3.3 or later and the sidekiq gem's adapter.
sidekiqDeprecates String#mb_chars and ActiveSupport::Multibyte::Chars.
String#mb_charsActiveSupport::Multibyte::CharsDeprecates using insert_all/upsert_all with unpersisted records in associations.
insert_allupsert_allDeprecates using update_all with WITH, WITH RECURSIVE or DISTINCT statements, which will raise in a future release.
update_alldelete_allDeprecates the built-in sidekiq adapter; use sidekiq 7.3.3 or later and the sidekiq gem's adapter.
sidekiqDeprecates the Benchmark.ms core extension as the benchmark gem becomes bundled in Ruby 3.5.
Benchmark.msDeprecates addition and since between two Time or ActiveSupport::TimeWithZone instances, to be removed in Rails 8.1.
TimeActiveSupport::TimeWithZonesinceDeprecates
unsigned_float and unsigned_decimal short-hand column methods.unsigned_floatunsigned_decimalDeprecates drawing routes with multiple paths to make routing faster.
with_optionsgetDeprecates
sucker_punch as an adapter option.sucker_punchadapter: asyncDeprecates
ActiveStorage::Service::AzureStorageService.ActiveStorage::Service::AzureStorageServiceDeprecates ::STATS_DIRECTORIES in favor of Rails::CodeStatistics.register_directory.
STATS_DIRECTORIESRails::CodeStatistics.register_directoryDeprecates bin/rake stats in favor of bin/rails stats.
bin/rake statsbin/rails statsDeprecates the Benchmark.ms core extension, since the benchmark gem becomes bundled in Ruby 3.5.
Benchmark.msDeprecates sucker_punch as an Active Job adapter option.
sucker_punchadapterDeprecates the ::STATS_DIRECTORIES constant in favor of Rails::CodeStatistics.register_directory.
STATS_DIRECTORIESRails::CodeStatistics.register_directory