first_or_create
кажется гораздо менее документированным, поэтому я задавался вопросом, было ли это только потому, что эти два метода являются синонимами.
First_or_create vs find_or_create_by
Ответ 1
В принципе:
Foo.where(attributes).first_or_create
То же, что и:
Foo.find_or_create_by(attributes)
#first_or_create
иногда неправильно понимается, поскольку люди ожидают его поиска по заданным атрибутам, но это не так. Ака
Foo.first_or_create(attributes)
Не будет искать foo
, удовлетворяющий attributes
. Он примет первый foo
, если таковые имеются. Это полезно, если условия для поиска являются подмножеством тех, которые используются для создания. Ака
Foo.where(something: value).first_or_create(attributes)
Найти первый foo
, где something: value
. Если ни один не присутствует, он будет использовать attributes
для его создания.
Ответ 2
Ответ @ndnenkov правильный, но я хотел бы find_or_create
на том, почему я думаю, что можно использовать find_or_create
:
Рассмотрим случай, когда Foo должен иметь attribute_subset_1
или attribute_subset_2
прежде чем его можно будет создать. Можно (псевдо) кодировать это как:
if attribute_subset_1 then
Foo.where(attribute_subset_1).first_or_create(attributes)
elsif attribute_subset_2 then
Foo.where(attribute_subset_2).first_or_create(attributes)
else
Raise error " insufficient attributes"
end
Это тот случай, когда я думаю, что find_or_create_by
не работает... по крайней мере, не легко. Мне было бы любопытно услышать, если что-то видит это по-другому, но я нашел, что использование first_or_create
идеально подходит для моих нужд.