lulu

【Rails】ModelのScopeの使い方

やること

あらかじめ決めておいた条件でレコードを取得できるRailsのScoopeの使い方を理解する

ver

  • ruby 2.5.1
  • Rails 6.0.3

Scope

RailsのScopeとは、Modelに記述することで、あらかじめ規定しておいた条件でレコードを取得できる

Userモデルに、20歳未満のスコープと名前検索するスコープを追加する

class User < ApplicationRecord
  scope :under_twenty, -> { where("age < ?", 20) }
  scope :include_name, -> (name) { where("name like ?", "%#{name}%") }
end

使い方

$ rails c

# userを準備
$ user1 = User.new(name: "テスト太郎", age: 21)
$ user1.save
$ user2 = User.new(name: "テスト次郎", age: 18)
$ user2.save
$ user3 = User.new(name: "あああ三郎", age: 16)
$ user3.save

# under_twenty scopeの使用
$ User.under_twenty
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE (age < 20) LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 8, age: 18, name: "テスト次郎", created_at: "2021-06-12 00:49:22", updated_at: "2021-06-12 00:49:22">, #<User id: 9, age: 16, name: "あああ三郎", created_at: "2021-06-12 00:49:26", updated_at: "2021-06-12 00:49:26">]>

# include_name scopeの使用
$ User.include_name("テスト")
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE (name like '%テスト%') LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 7, age: 21, name: "テスト太郎", created_at: "2021-06-12 00:49:14", updated_at: "2021-06-12 00:49:14">, #<User id: 8, age: 18, name: "テスト次郎", created_at: "2021-06-12 00:49:22", updated_at: "2021-06-12 00:49:22">]>

# 同時に適用することもできる
$ User.under_twenty.include_name("テスト")
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE (age < 20) AND (name like '%テスト%') LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 8, age: 18, name: "テスト次郎", created_at: "2021-06-12 00:49:22", updated_at: "2021-06-12 00:49:22">]>

まとめ

RailsのModelにscopeを使えば、あらかじめ規定しておいた条件でレコードを絞り込める。
また、User.under_twenty.include_name("テスト")のように、連結して使うことで、呼び出し元から「20歳未満の○○という名前のレコード」という意味を推察することができるようになる