7

Rails 7 adds `Enumerable#sole` to return a sole item in the enumerable

 3 years ago
source link: https://blog.saeloun.com/2021/05/26/rails-7-adds-enumerable-sole
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Rails 7 adds `Enumerable#sole` to return a sole item in the enumerable

May 26, 2021 , by Prasad Walvekar 1 minute read

Rails 6.1 added two query options, namely #sole and #find_sole_by to the ActiveRecord::FinderMethods. These methods assert that only one unique record is returned from the database.

In Rails 7, Enumerable#sole was added to the Enumerable module which behaves similar to ActiveRecord::FinderMethods methods - #sole and #find_sole_by.

Before

Let’s say we have an app where User can have multiple api_keys associated with their accounts. Each api_key will be associated with a particular type. To implement the above scenario we will design our User and ApiKey models as shown below:


# app/models/user.rb
class User < ApplicationRecord
  has_many :api_keys
end


# app/models/api_key.rb
class ApiKey < ApplicationRecord
  belongs_to :user

  scope :github, -> { where(key_type: "github") }

  # == Schema Information
  #
  # Table name: api_keys
  #
  # key                       :string(255)
  # user_id                   :integer
  # key_type                  :string(255)
end

To verify if a user has only one API key of a particular type, we might implement the following code:


user = User.find(1)
keys = user.api_keys.github.pluck(:key)

if keys.length == 1
  key = keys.first
elsif keys.length == 0
  raise "No records found!"
else
  raise "More than one matching record found!"
end

As seen, we have to write a lot of code to fetch a user API key of a particular type.

After

In Rails 7, with Enumerable#sole we can replace the above code as shown below:


key = user.api_keys.github.pluck(:key).sole
=> "github key"

The Enumerable#sole method returns one and only one element and raises an error if there are none or more than one element present in the Enumerable.


key = user.api_keys.github.pluck(:key).sole

# if no API key of particular type exists
=> Enumerable::SoleItemExpectedError (no item found)

# if multiple API keys of a particular type exist
=> Enumerable::SoleItemExpectedError (multiple items found)

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK