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:
parent
8544c9c236
commit
f64b5fb942
4 changed files with 28 additions and 19 deletions
|
@ -17,24 +17,18 @@ module ActiveRecord
|
||||||
|
|
||||||
def build(attributes = nil, &block)
|
def build(attributes = nil, &block)
|
||||||
block = _deprecated_scope_block("new", &block)
|
block = _deprecated_scope_block("new", &block)
|
||||||
@association.scoping(self) do
|
scoping { @association.build(attributes, &block) }
|
||||||
@association.build(attributes, &block)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
alias new build
|
alias new build
|
||||||
|
|
||||||
def create(attributes = nil, &block)
|
def create(attributes = nil, &block)
|
||||||
block = _deprecated_scope_block("create", &block)
|
block = _deprecated_scope_block("create", &block)
|
||||||
@association.scoping(self) do
|
scoping { @association.create(attributes, &block) }
|
||||||
@association.create(attributes, &block)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create!(attributes = nil, &block)
|
def create!(attributes = nil, &block)
|
||||||
block = _deprecated_scope_block("create!", &block)
|
block = _deprecated_scope_block("create!", &block)
|
||||||
@association.scoping(self) do
|
scoping { @association.create!(attributes, &block) }
|
||||||
@association.create!(attributes, &block)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -41,7 +41,6 @@ module ActiveRecord
|
||||||
reflection.check_validity!
|
reflection.check_validity!
|
||||||
|
|
||||||
@owner, @reflection = owner, reflection
|
@owner, @reflection = owner, reflection
|
||||||
@_scope = nil
|
|
||||||
|
|
||||||
reset
|
reset
|
||||||
reset_scope
|
reset_scope
|
||||||
|
@ -98,7 +97,11 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def scope
|
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
|
end
|
||||||
|
|
||||||
def reset_scope
|
def reset_scope
|
||||||
|
@ -198,13 +201,6 @@ module ActiveRecord
|
||||||
_create_record(attributes, true, &block)
|
_create_record(attributes, true, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def scoping(relation, &block)
|
|
||||||
@_scope = relation
|
|
||||||
relation.scoping(&block)
|
|
||||||
ensure
|
|
||||||
@_scope = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def find_target
|
def find_target
|
||||||
if owner.strict_loading?
|
if owner.strict_loading?
|
||||||
|
|
|
@ -224,6 +224,18 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
||||||
def test_build_and_create_from_association_should_respect_passed_attributes_over_default_scope
|
def test_build_and_create_from_association_should_respect_passed_attributes_over_default_scope
|
||||||
car = Car.create(name: "honda")
|
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")
|
bulb = car.bulbs.build(name: "exotic")
|
||||||
assert_equal "exotic", bulb.name
|
assert_equal "exotic", bulb.name
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ class Bulb < ActiveRecord::Base
|
||||||
belongs_to :car, touch: true
|
belongs_to :car, touch: true
|
||||||
scope :awesome, -> { where(frickinawesome: 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
|
after_initialize :record_scope_after_initialize
|
||||||
def record_scope_after_initialize
|
def record_scope_after_initialize
|
||||||
|
@ -17,6 +17,13 @@ class Bulb < ActiveRecord::Base
|
||||||
@attributes_after_initialize = attributes.dup
|
@attributes_after_initialize = attributes.dup
|
||||||
end
|
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)
|
def color=(color)
|
||||||
self[:color] = color.upcase + "!"
|
self[:color] = color.upcase + "!"
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue