-
Notifications
You must be signed in to change notification settings - Fork 22.1k
Closed
Description
Steps to reproduce
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "rails", "~> 8"
gem "sqlite3"
gem "debug"
end
require "active_record/railtie"
require "minitest/autorun"
# This connection will do for database-independent bug reports.
ENV["DATABASE_URL"] = "sqlite3::memory:"
class TestApp < Rails::Application
config.load_defaults Rails::VERSION::STRING.to_f
config.eager_load = false
config.logger = Logger.new($stdout)
config.secret_key_base = "secret_key_base"
end
Rails.application.initialize!
ActiveRecord::Schema.define do
create_table :posts, force: true
end
class Post < ActiveRecord::Base
end
class BugTest < ActiveSupport::TestCase
def test_association_stuff
Post.create!
Post.create!
begin
posts = Post.where("1=1").sole
rescue ActiveRecord::SoleRecordExceeded => e
# assert_equal "ActiveRecord::Relation", e.record.class.name # Works in Rails 7
assert_equal "Class", e.record.class.name # Works in Rails 8
end
end
end# Before
def something
items = Item.where(role: :admin).sole
rescue ActiveRecord::SoleRecordExceeded => e
e.record # Before 8.x, this includes only the first two items from the AR collection
end# After
def something
items = Item.where(role: :admin).sole
rescue ActiveRecord::SoleRecordExceeded => e
e.record # Now it contains the model itself, so the collection differs
endExpected behavior
In the latest 7.x release, the #sole method raised an ActiveRecord::SoleRecordExceeded exception using self as the argument, whereas in 8.x it now passes model instead.
- 7.x: https://github.com/rails/rails/blob/v7.2.3/activerecord/lib/active_record/relation/finder_methods.rb#L149
- 8.x: https://github.com/rails/rails/blob/v8.0.4/activerecord/lib/active_record/relation/finder_methods.rb#L151
This behavior change was introduced in the following commit: fd5bd98
Actual behavior
I couldn’t find any mention of this change in the changelogs, and it should be documented because it affects how we use this collection. Also, since we now only receive the model itself, we lose scopes and other collection filters, which could potentially lead to data leaks, what do you think?
System configuration
Rails version: 8.x
Ruby version: 3.4.6 (but doesn't matter here)
Metadata
Metadata
Assignees
Labels
No labels