Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix new instance creation on association relation to respect unscope #37511

Merged
merged 1 commit into from Oct 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 12 additions & 6 deletions activerecord/lib/active_record/association_relation.rb
Expand Up @@ -15,20 +15,26 @@ def ==(other)
other == records
end

def build(*args, &block)
def build(attributes = nil, &block)
block = _deprecated_scope_block("new", &block)
scoping { @association.build(*args, &block) }
@association.enable_scoping do
scoping { @association.build(attributes, &block) }
end
end
alias new build

def create(*args, &block)
def create(attributes = nil, &block)
block = _deprecated_scope_block("create", &block)
scoping { @association.create(*args, &block) }
@association.enable_scoping do
scoping { @association.create(attributes, &block) }
end
end

def create!(*args, &block)
def create!(attributes = nil, &block)
block = _deprecated_scope_block("create!", &block)
scoping { @association.create!(*args, &block) }
@association.enable_scoping do
scoping { @association.create!(attributes, &block) }
end
end

private
Expand Down
14 changes: 13 additions & 1 deletion activerecord/lib/active_record/associations/association.rb
Expand Up @@ -43,6 +43,7 @@ def initialize(owner, reflection)
reflection.check_validity!

@owner, @reflection = owner, reflection
@enable_scoping = false

reset
reset_scope
Expand Down Expand Up @@ -199,6 +200,13 @@ def create!(attributes = {}, &block)
_create_record(attributes, true, &block)
end

def enable_scoping
@enable_scoping = true
yield
ensure
@enable_scoping = false
end

private
def find_target
scope = self.scope
Expand Down Expand Up @@ -229,7 +237,11 @@ def association_scope
# Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
# through association's scope)
def target_scope
AssociationRelation.create(klass, self).merge!(klass.scope_for_association)
AssociationRelation.create(klass, self).merge!(scope_for_association)
end

def scope_for_association
@enable_scoping ? klass.all : klass.scope_for_association
end

def scope_for_create
Expand Down
25 changes: 25 additions & 0 deletions activerecord/test/cases/associations/has_many_associations_test.rb
Expand Up @@ -216,6 +216,9 @@ def test_create_from_association_should_respect_default_scope

bulb = car.bulbs.create
assert_equal "defaulty", bulb.name

bulb = car.bulbs.create!
assert_equal "defaulty", bulb.name
end

def test_build_and_create_from_association_should_respect_passed_attributes_over_default_scope
Expand All @@ -227,11 +230,30 @@ def test_build_and_create_from_association_should_respect_passed_attributes_over
bulb = car.bulbs.create(name: "exotic")
assert_equal "exotic", bulb.name

bulb = car.bulbs.create!(name: "exotic")
assert_equal "exotic", bulb.name

bulb = car.awesome_bulbs.build(frickinawesome: false)
assert_equal false, bulb.frickinawesome

bulb = car.awesome_bulbs.create(frickinawesome: false)
assert_equal false, bulb.frickinawesome

bulb = car.awesome_bulbs.create!(frickinawesome: false)
assert_equal false, bulb.frickinawesome
end

def test_build_and_create_from_association_should_respect_unscope_over_default_scope
car = Car.create(name: "honda")

bulb = car.bulbs.unscope(where: :name).build
assert_nil bulb.name

bulb = car.bulbs.unscope(where: :name).create
assert_nil bulb.name

bulb = car.bulbs.unscope(where: :name).create!
assert_nil bulb.name
end

def test_build_from_association_should_respect_scope
Expand Down Expand Up @@ -2504,6 +2526,7 @@ def test_association_with_rewhere_doesnt_set_inverse_instance_key
assert_equal 0, Client.count
end
end
assert_equal "lol", client.name
assert_equal [client], firm.clients_of_firm
end

Expand All @@ -2515,6 +2538,7 @@ def test_association_with_rewhere_doesnt_set_inverse_instance_key
assert_equal 0, Client.count
end
end
assert_equal "lol", client.name
assert_equal [client], firm.clients_of_firm
assert_equal [client], firm.reload.clients_of_firm
end
Expand All @@ -2527,6 +2551,7 @@ def test_association_with_rewhere_doesnt_set_inverse_instance_key
assert_equal 0, Client.count
end
end
assert_equal "lol", client.name
assert_equal [client], firm.clients_of_firm
assert_equal [client], firm.reload.clients_of_firm
end
Expand Down