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:
parent
90c19240c5
commit
18f83faf71
2 changed files with 41 additions and 2 deletions
|
@ -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,
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
Loading…
Reference in a new issue