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

#create_or_find_by/!: add more tests and fix docs (#34653)

* `#create_or_find_by/!`: add more tests

* Fix docs of `create_or_find_by`

This method uses `find_by!` internally.
This commit is contained in:
Bogdan 2018-12-08 00:46:30 +02:00 committed by Ryuta Kamizono
parent 90c19240c5
commit 18f83faf71
2 changed files with 41 additions and 2 deletions

View file

@ -163,7 +163,7 @@ module ActiveRecord
# Attempts to create a record with the given attributes in a table that has a unique constraint
# on one or several of its columns. If a row already exists with one or several of these
# unique constraints, the exception such an insertion would normally raise is caught,
# and the existing record with those attributes is found using #find_by.
# and the existing record with those attributes is found using #find_by!.
#
# This is similar to #find_or_create_by, but avoids the problem of stale reads between the SELECT
# and the INSERT, as that method needs to first query the table, then attempt to insert a row
@ -173,7 +173,7 @@ module ActiveRecord
#
# * The underlying table must have the relevant columns defined with unique constraints.
# * A unique constraint violation may be triggered by only one, or at least less than all,
# of the given attributes. This means that the subsequent #find_by may fail to find a
# of the given attributes. This means that the subsequent #find_by! may fail to find a
# matching record, which will then raise an <tt>ActiveRecord::RecordNotFound</tt> exception,
# rather than a record with the given attributes.
# * While we avoid the race condition between SELECT -> INSERT from #find_or_create_by,

View file

@ -1315,6 +1315,13 @@ class RelationTest < ActiveRecord::TestCase
assert_not_equal subscriber, Subscriber.create_or_find_by(nick: "cat")
end
def test_create_or_find_by_should_not_raise_due_to_validation_errors
assert_nothing_raised do
bird = Bird.create_or_find_by(color: "green")
assert_predicate bird, :invalid?
end
end
def test_create_or_find_by_with_non_unique_attributes
Subscriber.create!(nick: "bob", name: "the builder")
@ -1334,6 +1341,38 @@ class RelationTest < ActiveRecord::TestCase
end
end
def test_create_or_find_by_with_bang
assert_nil Subscriber.find_by(nick: "bob")
subscriber = Subscriber.create!(nick: "bob")
assert_equal subscriber, Subscriber.create_or_find_by!(nick: "bob")
assert_not_equal subscriber, Subscriber.create_or_find_by!(nick: "cat")
end
def test_create_or_find_by_with_bang_should_raise_due_to_validation_errors
assert_raises(ActiveRecord::RecordInvalid) { Bird.create_or_find_by!(color: "green") }
end
def test_create_or_find_by_with_bang_with_non_unique_attributes
Subscriber.create!(nick: "bob", name: "the builder")
assert_raises(ActiveRecord::RecordNotFound) do
Subscriber.create_or_find_by!(nick: "bob", name: "the cat")
end
end
def test_create_or_find_by_with_bang_within_transaction
assert_nil Subscriber.find_by(nick: "bob")
subscriber = Subscriber.create!(nick: "bob")
Subscriber.transaction do
assert_equal subscriber, Subscriber.create_or_find_by!(nick: "bob")
assert_not_equal subscriber, Subscriber.create_or_find_by!(nick: "cat")
end
end
def test_find_or_initialize_by
assert_nil Bird.find_by(name: "bob")