【Railsのモデルで使用】scopeのlambdaとは何なのか?使い方を紹介

Not image

みなさんは、Railsでアプリケーションを作成している際、scopeというものを使っていますか?

もし使う機会がある方やいま実際使っている方は、scopeとセットで出てくるlambdaというものを知っておかなくてはなりません。

とても便利で綺麗にコードを書くことができるため、今回の記事でしっかり押さえておきましょう。

そこで今回は、scopeとlambdaとはなんなんのかということ・scopeとlambdaの使い方をまとめていこうと思います。

scopeとはなんなのか?

そもそもscopeとはなんなのかという問題です。

Railsを触った方なら、コントローラやモデルなどからActive Recordを通してDBの情報を参照することが多々ありますよね。そんな中で複雑な検索が必要な場合、検索パターンをメソッドチェーンにして複雑な検索に対応しているのではないでしょうか?

下の例のように、メソッドをいくつも繋げて複雑な検索をしていませんか?

User.where(status: 1).order(created_at: "DESC").limit(10)

このように検索パターンが複雑になると、可読性が下がってしまいます。

可読性が落ちるだけでなく、「他のところでもこの検索パターンを使いたい!」という場合にもう一度同じ検索パターンを書くことになってしまいます。

これでは、Railsの思想であるDRYに反するコードが出来上がってしまいます。

そこで使うのが、「scope」ということなんですね。

scopeを使うと、検索パターンを複数の場所で使えるようになります。(メソッドのように使えるようになります。)

また、検索対象となるモデルファイルに一元的に記述するので、整理され可読性が上がります

lambdaとはなんなのか?

次はlambdaについて説明していきます。

lambdaの正体は、無名関数というものです。さらに無名関数の正体は、RubyのProcオブジェクトというものになります。無名関数とは、名前のままの意味で「名前のない関数」です。「無名関数、無名関数」といきなり言われてもイメージが掴みづらいと思うので、下のコードを見てみてください。

上のコードのように、普段作る関数と同じようにlambdaは関数として振る舞います。

また、lambdaは「->」というものに置き換わっていることがあります。

Railsアプリのモデルを見ているとscope+lambdaもしくは「->」をよく見るのではないでしょうか。これは、lambdaのアロー演算子という記法を用いた形なので、どちらもlambdaなんだなと考えて大丈夫です。

先ほどProcオブジェクトというものが登場しましたが、Procオブジェクトについては以下の記事にまとめたので気になる方は見てみてください。

【ブロック?yield?】RubyのProcオブジェクトをしっかり理解する

2018.10.24

scopeとlambdaの使い方

scopeの使い方①:基本

上記のように、beforeではcontrollerに検索パターンを書いています。

scopeを使うと、controllerではscopeを呼び出すのみで、modelに検索パターンをまとめてあります。

他の場所から検索パターンを呼び出すことも可能になる。

scopeの使い方②:引数を渡す

引数を渡すには、上記のようにするだけです。

scopeの使い方③:scopeを結合

一つ一つは単純な検索パターンでも、相互に組み合わせることでより複雑な検索パターンを創出することができます。

scopeの使い方④:default_scope

上記のように、default_scopeを設定するとidが1のものをSampleに対する検索時にデフォルトで実行するような設定になります。

これは、論理削除の際に使われることが多いです。DBのレコードを物理的には削除していないが、「このレコードは削除と見なす」としたい時にdefault_scopeで制御できます。

まとめ

今回はRailsの検索をscopeを使って、可読性・保守性を高い状態に維持することを学びました。

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

最初は、あまり直感的にイメージできないかもしれませんが、何度も触れていると読めるように・書けるようになると思っています。

さらにRailsでは、コントローラは薄く保つことが主流の書き方になっています。つまり今回の検索パターンもscopeを使って、modelやconcernに切り出してコントローラを薄く保つように心がけてみてください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です