高木のブログ

【Rails】スコープとクラスメソッドの違い

· 261 words · 2 minutes to read
Tags: Rails

普通に実装していたら違いなんてなくてどっちでもいいじゃんって思ってたけど、明確な違いがあった
今までたまたまそういう実装をしていないからハマらなかっただけで、いつかハマるかもしれないからメモしておく

スコープとクラスメソッドの違い 🔗

メソッドチェインができるようにスコープはActiveRecord::Relationを返すようになっている

どういう時にハマる可能性があるか 🔗

以下のようなfind_ageスコープを作成

class User < ApplicationRecord
  scope :find_age, ->(age) { find_by(age: age) }
end

条件に一致するレコードがある場合は特に問題ない 🔗

[1] pry(main)> User.find_age(27)
  User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`age` = 27 LIMIT 1
=> #<User:0x00007f3b4dc32b18
 id: 1,
 name: "takagi",
 age: 27,
 created_at: Sat, 08 Aug 2020 22:07:38 JST +09:00,
 updated_at: Sat, 08 Aug 2020 22:07:38 JST +09:00>

条件に一致するレコードがない場合は全件返ってくる 🔗

[1] pry(main)> User.find_age(30)
  User Load (0.5ms)  SELECT `users`.* FROM `users` WHERE `users`.`age` = 30 LIMIT 1
=>   User Load (0.2ms)  SELECT `users`.* FROM `users`
[#<User:0x00007f3b4dd94448
  id: 1,
  name: "takagi",
  age: 27,
  created_at: Sat, 08 Aug 2020 22:07:38 JST +09:00,
  updated_at: Sat, 08 Aug 2020 22:07:38 JST +09:00>,
 #<User:0x00007f3b4dd94380
  id: 2,
  name: "tanaka",
  age: 25,
  created_at: Sat, 08 Aug 2020 22:07:53 JST +09:00,
  updated_at: Sat, 08 Aug 2020 22:07:53 JST +09:00>,
 #<User:0x00007f3b4dd942b8
  id: 3,
  name: "sato",
  age: 32,
  created_at: Sat, 08 Aug 2020 22:09:52 JST +09:00,
  updated_at: Sat, 08 Aug 2020 22:09:52 JST +09:00>]

find_byメソッドは条件に当てはまるレコードがないときはnilを返す仕様
スコープはActiveRecord::Relationを必ず返す仕様なので、nilではなくallと同じ結果のActiveRecord::Relationを返す

わかりやすくnilを返すスコープを用意 🔗

scope :return_nil, -> { nil }
[1] pry(main)> User.return_nil
=>   User Load (0.4ms)  SELECT `users`.* FROM `users`
[#<User:0x00007f3b4dd94448
  id: 1,
  name: "takagi",
  age: 27,
  created_at: Sat, 08 Aug 2020 22:07:38 JST +09:00,
  updated_at: Sat, 08 Aug 2020 22:07:38 JST +09:00>,
 #<User:0x00007f3b4dd94380
  id: 2,
  name: "tanaka",
  age: 25,
  created_at: Sat, 08 Aug 2020 22:07:53 JST +09:00,
  updated_at: Sat, 08 Aug 2020 22:07:53 JST +09:00>,
 #<User:0x00007f3b4dd942b8
  id: 3,
  name: "sato",
  age: 32,
  created_at: Sat, 08 Aug 2020 22:09:52 JST +09:00,
  updated_at: Sat, 08 Aug 2020 22:09:52 JST +09:00>]

User.allと同じ結果になる

参考 🔗

Categories


Tags