提交 18f83faf 编写于 作者: B Bogdan 提交者: Ryuta Kamizono

#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.
上级 90c19240
......@@ -163,7 +163,7 @@ def find_or_create_by!(attributes, &block)
# 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 @@ def find_or_create_by!(attributes, &block)
#
# * 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 @@ def test_create_or_find_by
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 @@ def test_create_or_find_by_within_transaction
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")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册