`sole` Method Is Going to Be Introduced into ActiveRecord and Enumerable
Posted on by Gentaro "hibariya" Terada
Today I learned that Rails 6.1.3 does not have methods that raise exceptions when more than one record was found. However, in future versions, we could use ActiveRecord::FinderMethods#sole
for that purpose. It seems Enumerable#sole
is also going to be introduced.
Sometimes I need to make sure there is one and only one record that matches a condition without using a unique-index, for example, when I cannot add that constraint to the database.
ActiveRecord::FinderMethods#first!
raises ActiveRecord::RecordNotFound
when no records is found but it does not raise exceptions when multiple records found. It does not assure that there is no other records. To make sure there is one and only one record for a condition, upcoming ActiveRecord::FinderMethods#sole
would be useful.
According to rails/rails#40768, we can use that like this (experpt from the changelog):
Product.where(["price = %?", price]).sole
# => ActiveRecord::RecordNotFound (if no Product with given price)
# => #<Product ...> (if one Product with given price)
# => ActiveRecord::SoleRecordExceeded (if more than one Product with given price)
Also, there is another pull request rails/rails#40914 that adds the same method to Enumerable.