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

Allow extra scoping in callbacks when create on association relation

#37523 has a regression that ignore extra scoping in callbacks when
create on association relation.

It should respect `klass.current_scope` even when create on association
relation to allow extra scoping in callbacks.

Fixes #38741.
This commit is contained in:
Ryuta Kamizono 2020-03-21 23:10:34 +09:00
parent 8544c9c236
commit f64b5fb942
4 changed files with 28 additions and 19 deletions

View file

@ -17,24 +17,18 @@ module ActiveRecord
def build(attributes = nil, &block)
block = _deprecated_scope_block("new", &block)
@association.scoping(self) do
@association.build(attributes, &block)
end
scoping { @association.build(attributes, &block) }
end
alias new build
def create(attributes = nil, &block)
block = _deprecated_scope_block("create", &block)
@association.scoping(self) do
@association.create(attributes, &block)
end
scoping { @association.create(attributes, &block) }
end
def create!(attributes = nil, &block)
block = _deprecated_scope_block("create!", &block)
@association.scoping(self) do
@association.create!(attributes, &block)
end
scoping { @association.create!(attributes, &block) }
end
private

View file

@ -41,7 +41,6 @@ module ActiveRecord
reflection.check_validity!
@owner, @reflection = owner, reflection
@_scope = nil
reset
reset_scope
@ -98,7 +97,11 @@ module ActiveRecord
end
def scope
@_scope&.spawn || target_scope.merge!(association_scope)
if (scope = klass.current_scope) && scope.try(:proxy_association) == self
scope.spawn
else
target_scope.merge!(association_scope)
end
end
def reset_scope
@ -198,13 +201,6 @@ module ActiveRecord
_create_record(attributes, true, &block)
end
def scoping(relation, &block)
@_scope = relation
relation.scoping(&block)
ensure
@_scope = nil
end
private
def find_target
if owner.strict_loading?

View file

@ -224,6 +224,18 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_build_and_create_from_association_should_respect_passed_attributes_over_default_scope
car = Car.create(name: "honda")
bulb = car.bulbs.where(name: "exotic").build
assert_equal "exotic", bulb.name
assert_nil bulb.count_after_create
bulb = car.bulbs.where(name: "exotic").create
assert_equal "exotic", bulb.name
assert_equal 1, bulb.count_after_create
bulb = car.bulbs.where(name: "exotic").create!
assert_equal "exotic", bulb.name
assert_equal 2, bulb.count_after_create
bulb = car.bulbs.build(name: "exotic")
assert_equal "exotic", bulb.name

View file

@ -5,7 +5,7 @@ class Bulb < ActiveRecord::Base
belongs_to :car, touch: true
scope :awesome, -> { where(frickinawesome: true) }
attr_reader :scope_after_initialize, :attributes_after_initialize
attr_reader :scope_after_initialize, :attributes_after_initialize, :count_after_create
after_initialize :record_scope_after_initialize
def record_scope_after_initialize
@ -17,6 +17,13 @@ class Bulb < ActiveRecord::Base
@attributes_after_initialize = attributes.dup
end
after_create :record_count_after_create
def record_count_after_create
@count_after_create = Bulb.unscoped do
car&.bulbs&.count
end
end
def color=(color)
self[:color] = color.upcase + "!"
end