Rails first_or_create vs find_or_create_by on ActiveRecord
Rails ActiveRecord provides methods like first_or_create, find_or_create_by methods to insert data based on certain conditions or create new records. We need to understand difference between first_or_create and find_or_create_by to use them as per need.
First things first, first_or_create
is not available in Public API anymore.
Documentation for
Find or Build a New Object
on Rails documentation does not enlist method(s) first_or_create
and
first_or_create!
methods anymore.
They were listed in documentation
previously.
Since, it was available in public documentation previously
and
people started using it in their repositories,
it has created some confusion with
newly available methods such as
find_or_create_by
and
find_or_create_by!
to perform similar functionality.
first_or_create
Listing down some code using first_or_create
below.
What do you expect to happen if the code is run?
- Return first record or create a user with
name
asJohn Doe
andemail
as[email protected]
Well, the first part of the sentence above,
Return first record
This means, it will return any first record from the table Project
.
It does not use the conditions passed to query and find the record to return if exists.
This causes confusion as we pass arguments to first_or_create
which are
name
equals Ruby on Rails
and status
equals active
,
we may end up assuming that first_or_create
will find a record
that satisfies this condition
and
return it
otherwise
it will create a new record with given conditions.
That’s why, Rails has added find_or_create_by
variant
and
make available in public API.
So, when first_or_create is useful?
We can use first_or_create
without where
clause,
if we just want to make sure some record exists in the target table.
We can also use first_or_create
coupled with where
clause to
get the desired result as given below.
Now, this will first search for a Project
with given conditions in where clause,
if the record exists, it will be returned.
Otherwise, it will create record with those conditions.
find_or_create_by
Find or create by method on ActiveRecord relation makes it explicitely clear that,
- it will find records with given where conditions, return record it exists
- otherwise it will create a new record with given conditions
This is exactly same as the query with first_or_create
along with where
clause explained above.
Conclusion
It is important to understand subtle differences between methods first_or_create
and find_or_create_by
methods on ActiveRecord in Rails
to
effectively use them as per the need.
Subscribe to Ruby in Rails
Get the latest posts delivered right to your inbox