delhi09の勉強日記

技術トピック専用のブログです。自分用のメモ書きの投稿が多いです。あくまで「勉強日記」なので記事の内容は鵜呑みにしないでください。

RailsのActiveRecordでscopeを使う ※ 引数あり/なしパターン

RailsActiveRecordでscopeを使う方法です。

scopeとはよく使う条件をメソッド化できるActiveRecordの機能です。

引数なしのパターン

以下のように定義します。

class Restaurant < ApplicationRecord
  # 省略
  scope :south_india, -> { joins(:tags).where(tags: { name: "南インド" }) }
end

Restaurantモデルのメソッドとして呼び出すことができます。

app(dev):002> Restaurant.south_india.count
  Restaurant Count (8.6ms)  SELECT COUNT(*) FROM "restaurants" INNER JOIN "restaurants_tags" ON "restaurants_tags"."restaurant_id" = "restaurants"."id" INNER JOIN "tags" ON "tags"."id" = "restaurants_tags"."tag_id" WHERE "tags"."name" = '南インド' /*application='App'*/
=> 1

引数ありのパターン

引数を渡すこともできます。その場合は以下のように定義します。

class Restaurant < ApplicationRecord
  # 省略
  scope :has_tag, -> (name){ joins(:tags).where(tags: { name: name }) }
end

以下のようにscope呼び出し時に引数を渡すことができます。発行されているSQLは引数なしパターンと同じになっています。

app(dev):003> Restaurant.has_tag("南インド").count
  Restaurant Count (9.3ms)  SELECT COUNT(*) FROM "restaurants" INNER JOIN "restaurants_tags" ON "restaurants_tags"."restaurant_id" = "restaurants"."id" INNER JOIN "tags" ON "tags"."id" = "restaurants_tags"."tag_id" WHERE "tags"."name" = '南インド' /*application='App'*/
=> 1