1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fix user-defined self.default_scope to respect table alias

If a model which has a user-defined `self.default_scope` is joined with
table alias, a user-defined `self.default_scope` ignores table alias.

This problem has potentially existed for a long time, but it has not
become apparent because it is difficult to meet this condition.

Since #40106, table alias is easily used if association names are used
in `where`.

So user-defined `self.default_scope` should be evaluated in the current
aliased relation.

Fixes #41857.
This commit is contained in:
Ryuta Kamizono 2021-04-09 19:26:01 +09:00
parent 3b1fae47db
commit b576dd02af
2 changed files with 5 additions and 6 deletions

View file

@ -146,9 +146,7 @@ module ActiveRecord
if default_scope_override
# The user has defined their own default scope method, so call that
evaluate_default_scope do
if scope = default_scope
relation.merge!(scope)
end
relation.scoping { default_scope }
end
elsif default_scopes.any?
evaluate_default_scope do

View file

@ -76,6 +76,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
class Album < ActiveRecord::Base
self.table_name = "music.albums"
has_and_belongs_to_many :songs
def self.default_scope; where(deleted: false); end
end
def setup
@ -149,14 +150,14 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
ActiveRecord::Base.connection.drop_schema "music", if_exists: true
ActiveRecord::Base.connection.create_schema "music"
ActiveRecord::Base.connection.execute <<~SQL
CREATE TABLE music.albums (id serial primary key);
CREATE TABLE music.albums (id serial primary key, deleted boolean default false);
CREATE TABLE music.songs (id serial primary key);
CREATE TABLE music.albums_songs (album_id integer, song_id integer);
SQL
song = Song.create
Album.create
assert_equal song, Song.includes(:albums).references(:albums).first
album = song.albums.create
assert_equal song, Song.includes(:albums).where("albums.id": album.id).first
ensure
ActiveRecord::Base.connection.drop_schema "music", if_exists: true
end