Execute default_scope defined by abstract class within the scope of subclass

This commit is contained in:
Mehmet Emin İNAÇ 2016-02-14 01:59:11 +02:00
parent a61bf5f5b6
commit 0784dccc4f
5 changed files with 38 additions and 1 deletions

@ -1,3 +1,9 @@
* Execute default_scope defined by abstract class in the context of subclass.
Fixes #23413 & #10658
*Mehmet Emin İNAÇ*
* Fix an issue when preloading associations with extensions.
Previously every association with extension methods was transformed into an
instance dependent scope. This is no longer the case.

@ -115,7 +115,8 @@ def build_default_scope(base_rel = nil) # :nodoc:
base_rel ||= relation
evaluate_default_scope do
default_scopes.inject(base_rel) do |default_scope, scope|
default_scope.merge(base_rel.scoping { scope.call })
scope = scope.respond_to?(:to_proc) ? scope : scope.method(:call)
default_scope.merge(base_rel.instance_exec(&scope))
end
end
end

@ -4,6 +4,7 @@
require 'models/developer'
require 'models/computer'
require 'models/vehicle'
require 'models/cat'
class DefaultScopingTest < ActiveRecord::TestCase
fixtures :developers, :posts, :comments
@ -485,4 +486,15 @@ def test_sti_conditions_are_not_carried_in_default_scope
assert_equal 1, SubConditionalStiPost.all.to_a.size
assert_equal 2, SubConditionalStiPost.unscope(where: :title).to_a.size
end
def test_with_abstract_class_scope_should_be_executed_in_correct_context
vegetarian_pattern, gender_pattern = if current_adapter?(:Mysql2Adapter)
[/`lions`.`is_vegetarian`/, /`lions`.`gender`/]
else
[/"lions"."is_vegetarian"/, /"lions"."gender"/]
end
assert_match vegetarian_pattern, Lion.all.to_sql
assert_match gender_pattern, Lion.female.to_sql
end
end

@ -0,0 +1,13 @@
class Cat < ActiveRecord::Base
self.abstract_class = true
enum gender: [:female, :male]
scope :female, -> { where(gender: genders[:female]) }
scope :male, -> { where(gender: genders[:male]) }
default_scope -> { where(is_vegetarian: false) }
end
class Lion < Cat
end

@ -421,6 +421,11 @@ def except(adapter_names_to_exclude)
t.integer :amount
end
create_table :lions, force: true do |t|
t.integer :gender
t.boolean :is_vegetarian, default: false
end
create_table :lock_without_defaults, force: true do |t|
t.column :lock_version, :integer
end