【Rails入門】scopeの使い方まとめ

こんにちは! フリーエンジニアの長瀬です。

みなさんはscopeを使っていますか。

scopeを使えば、SQL文をメソッド化できるのでデータ管理を効率化できます。

この記事では、scopeの使い方について

・scope とは
・scopeの使い方

という基本的な内容から、

・scopeの応用的な使い方

といった一歩進んだ内容についても解説していきます。

scopeとは

モデルにscopeを設定することで、特定のSQL文をメソッド化して使えます。

なので、繰り返しよく使うSQL文があるときにはscopeを使って定義しておきましょう。

今回はUserモデルとPostモデルを使って解説するので、まずは以下のサンプルコードを入力してください。

[UserモデルとPostモデルを作成し、データベースに反映する]

これで、今回使うカラムとモデルが作成できました。

続いてデータを入れていきましょう。

rails consoleでコンソールを起動した後、以下のコードを入力してください。

[UserモデルとPostモデルに今回使うデータを入れる

これでデータが入りました。

続いて、UserとPostの関連付けを行いますので、それぞれのmodelに以下のサンプルコードを入力してください。

[app/models/user.rbに入力する内容]

[app/models/post.rbに記述する内容]

これで関連付けを設定できました。

では実際にscopeを使ってみましょう。

app/models/user.rbに以下のサンプルコードを入力してください。

[app/models/user.rbに入力する内容]

このようにyoungというscopeを設定したので、youngというメソッドが使えるようになります。

ここからはrails cosoleに取り出したデータを出力していくので、出力したデータの見栄えを良くにするために一つgemを追加します。(すでにインストール済みの方は飛ばしてもらってかまいません。)

まず、Gemfileに
[Gemfileに入力する内容]

を追記して、コマンドプロンプトで

[Gemfileの内容を反映する]

を入力してインストールしてください。

これで、いつでもHirb.enableとコーソールで入力すればHirbのgemが有効になります。

rails consoleでコンソールを起動した後、以下のコードを入力してください。

[自分で設定したyoungメソッドを使ってみる]

[実行結果]

モデルで設定したageが20以下のデータを取り出すyoungメソッドを使うことができました。

このようにscopeを定義すれば、よく使うSQL文をメソッド化して使えます。

これがscopeを使うメリットです。

scopeの基本構文

それでは、さきほど使ったscopeの構文を解説していきます。

[scopeで定義されたyoungメソッドの例]

scopeはmodels以下のモデル名.rbファイル内に記述にします。

まず、scope :(メソッドの名前)でメソッド名を定義してそれ以降の部分にSQL文を書いていきます。この構文はラムダ式と呼ばれるものです。

ラムダ(lambda)式とは

ラムダ式とは名前の通り、ラムダを使った式のことで、Rails4以降はscopeの定義にはラムダ式を使うことが必須になりました。

ラムダについて説明すると、1つの記事になってしまいます。

ですので、ここではラムダ式はいくつかのコードをまとめて1つのメソッドとして扱うことを実現してくれる便利なものという認識で大丈夫です。

Rubyにはラムダ(lamda)の他にProcという類似の機能があります。
気になる方はこちらの記事を参考にしてください。

さきほど、使ったサンプルコードを例にすると

scope以降の:young, -> 〜がラムダ式で記述されている部分です。

scopeの使い方

scopeの基本的な使い方

それではscopeを実践的に使っていきましょう。

まずはwhereを使ったscopeからです。

app/models/post.rbに以下のサンプルコードを入力してください。

[app/models/post.rbに入力する内容]

whereを使って定義したscopeを使っていきましょう。
rails consoleでコンソールを起動した後、以下のコードを入力してください。

[two_monthsメソッドを使ってデータを取り出す]

[実行結果]

このように、whereが適応されていることが確認できます。

続いて、orderです。

app/models/post.rbに以下のサンプルコードを入力してください。

[app/models/post.rbに入力する内容]

orderを使って定義したscopeを使っていきましょう。
rails consoleでコンソールを起動した後、以下のコードを入力してください。

[descメソッドを使ってデータを取り出す]

[実行結果]

orderで指定したcreated_atの降順でデータを取り出せました。

パラメータ付きのscopeの使い方

また、scopeにはパラメータを設定することもできます。

つまり、ラムダ式に引数を付けるということです。

以下のサンプルコードをapp/models/user.rbに入力してください。
[app/models/user.rbに入力する内容]

これでscopeが設定できたので、rails consoleでコンソールを開いて以下のコードを入力してください。

[設定したageメソッドを使ってみる]

[実行結果]

50を引き数として渡したので、ageが50よりも小さいuserが取り出されました。

このように、パラメータを設定することで、より柔軟に使えるメソッドを定義できます。

default_scopeの使い方

default_scopeを使えば、モデルに設定したscopeを反映した結果を常に出力できます。

てすが、defall_scopeは常に呼ばれるようになるので、使用上の注意が必要です。

この記事ではPostで削除された記事を表示させないように設定します。

[app/modes/post.rbにdefault_scopeを設定]

これで、deleted_atに日付が入力されているレコードは表示されなくなります。

実際にすべてのPostのレコードを取得してみましょう。

rails consoleでコンソールを起動した後、以下のコードを入力してください。

[Postの中身を全て表示するサンプルコード]

[実行結果]

このように、すべて取得しようとしてもdefault_scopeの効果でdelete_atに日付がある記事は表示されなくなりました。

ただdefault_scopeは毎回呼ばれるので、よくバグの原因になったりします。

なので、今回のように論理削除する場合など、使い所を限定して使いましょう。

scopeの応用的な使い方

それでは少し応用の効いたscopeの使い方を紹介します。

関連付けられた2つのデーブルをjoinsで内部結合するときに、scopeではmergeメソッドと組み合わせることで、別のモデルで設定したscopeを参照して使えます。

今回はorderの説明でPostモデルに設定したdescメソッドをUserモデルで使えるようにしてみます。

以下のサンプルコードをapp/models/user.rbに入力してください。
[app/models/user.rbに入力する内容]

次にapp/models/post.rbに以下のサンプルコードを入力してください。

[app/models/post.rbに入力する内容]

それでは、rails consoleでコンソールを起動した後、以下のコードを入力してUserモデルで設定したscopeを使っていきましょう。

[desc_postsメソッドを使うサンプルコード]

[実行結果]

Postのcreated_atカラムの日付の降順で内部結合し、データを取り出せました。

このように、joinsで内部結合して別のモデルで定義したscopeを使うときはmergeと組み合わせて使うようにしてください。

まとめ

いかがでしたでしょうか?

この記事では、scopeの使い方を解説しました。

今回紹介した基本的なwhereやorderを使ってscopeを定義するだけでも、SQL文をメソッド化できるので開発効率が上がります。

また適切なメソッド名をつけることで、より直感的にデータを扱えるようになるので、使えるところは積極的にscopeを定義していきましょう。

もしscopeの使い方について忘れてしまったらこの記事を確認してくださいね!

LINEで送る
Pocket

最短でエンジニアを目指すなら侍エンジニア塾

cta_under_bnr

侍エンジニア塾は業界で初めてマンツーマンレッスンを始めたプログラミングスクールです。これまでの指導実績は16,000名を超え、未経験から数多くのエンジニアを輩出しています。

あなたの目的に合わせてカリキュラムを作成し、現役エンジニア講師が専属であなたの学習をサポートするため効率よく学習を進めることができますよ。

無理な勧誘などは一切ありません。まずは無料体験レッスンを受講ください。

無料体験レッスンの詳細はこちら

書いた人

長瀬来

長瀬来

Unityを使ったiOSアプリのリリース、フリマサイト運営の経験があります。

経験した言語はC、C#、Javascript、R、Python、Ruby、PHPなど

言語が好きで、英語や中国、ドイツ語を勉強しました。
将来的には海外で生活したいです。

現在はRuby on Rails5やCocos2dxの勉強を主にしています。

ライターとしては
できるだけ初心者にわかりやすい文章になるように心がけています。

趣味は語学、読書です。

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説