こんにちは!システムエンジニアのオオイシです。
Ruby on Railsのany?メソッドをご存知ですか!?
「any?メソッドはどのような時に使うの?」
「present?メソッドじゃダメなの?」
「validationエラーの存在を確認する方法を知りたい。。。」
というそんなあなたに、今回は、
【基礎】any?メソッドとは
【基礎】any?メソッドの使いかた
【応用】any?とpresent?との違い
【応用】validationエラーでの応用
などについて解説いたします。
Railsのany?メソッドはモデルのデータを評価するための便利なメソッドですので、使い方をよく理解しておきましょう。
any?メソッドとは
any?メソッドとは、
- モデルにデータが存在する → true
- モデルにデータが存在しない → false
を返すメソッドです。
ブロックを使う場合は、ブロック内の条件が1つでもtrueになればany?メソッドがtrueを返します。
書き方:
モデル.any? モデル.where(検索条件).any? モデル.any? do | 変数 | [条件] # 例: 変数 >= 0 end
このようにとても簡単に使えるメソッドです。
次項ではany?メソッドの使いかたを見ていきましょう。
any?メソッドの使いかた
ここではany?メソッドの使いかたを紹介していきます。
any?メソッドの基本
はじめにname属性をもつSampleモデルを作成します。
サンプルモデル作成:
$ bin/rails g model Sample name:string
データが0件の場合はfalse、1件の場合はtrueを返却するサンプルプログラムを確認してみましょう。
Railsコンソールを使います。
サンプルコード:
# 0件の場合 > Sample.all.count => 0 > Sample.any? => false # 1件の場合 > Sample.create(name: "侍1") > Sample.any? => true
このようにデータが存在する時はtrueを返却することが確認できした。
where条件とany?メソッドの組み合わせ
実用的な使いかたとして、where検索データにany?メソッドを使う方法について紹介します。
検索結果の件数が1件以上の場合にany?メソッドはtrueを返します。
サンプルコードで確認してみましょう。
サンプルコード:
> Sample.where(name: "侍1").any? => true > Sample.where(name: "侍2").any? => false
このように、whereメソッドと組み合わせることができました。
なお、Railsコンソールについてはこちらで詳しく解説しているので、ぜひ参考にしてみてください。
ブロックに条件を指定
ブロック付きのany?メソッドは、ブロックに記述した条件が1つでもtrueになったらany?メソッドもtrueを返します。
サンプルコードを確認してみましょう。
> Sample.any? do | sample | sample.name == "侍2" end => false > Sample.any? do | sample | sample.name == "侍1" end => true
このように、ブロックを使った条件指定でany?メソッドを使うことができました。
any?とpresent?との違い
present?メソッドとany?メソッドとの違いについて紹介します。
結論からいうとany?メソッドの方が高速です。
- present? → 全てのデータを取得する
- any? → 1件のみデータを取得する
Railsが実行するSQLを比較して違いを確認してみましょう。
> Sample.where(name:"侍1").present? Sample Load (0.4ms) SELECT `samples`.* FROM `samples` WHERE `samples`.`name` = '侍1' => true > Sample.where(name:"侍1").any? Sample Exists (0.4ms) SELECT 1 AS one FROM `samples` WHERE `samples`.`name` = '侍1' LIMIT 1 => true
このように、SQLの最後にLIMIT 1 が付与されています。
このため、データ量に関係なく1件を取得するから高速なのです!
なお、Rubyのpresent?についてはこちらに詳しく紹介されています。
validationエラーでの応用
validationエラーのありなしの判定にもany?メソッドが利用できます。
例えば次のようなERBプログラムです。
サンプルコード:
<% if @sample.errors.any? %> <ul> <% @sample.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> <% end %>
そんなany?メソッドは、
- rubyの配列(Arrayクラス)
- validationエラーの配列(ActiveModel::Errorsクラス)
- モデル(Active Recordクラス)
で全て同じany?メソッドを使っています。
なぜならば、これらのクラスはEnumerableモジュールをインクルードしているためです。
そのため、全て同じ動きになります。
all?メソッドは、ブロック引数itemに要素を入れながらブロックを繰り返し実行し、ブロックが真が返したときは繰り返しを中断してtrueを返します。ブロックの戻り値がすべて偽であるとき、あるいはレシーバが空であるときにはfalseを返します。
出典:any? (Enumerable) – Rubyリファレンス
なお、includeについてはこちらで詳しく解説しています。
まとめ
いかかでしたか?
今回は、Railsのany?メソッドの使い方をについて解説しました。
any?メソッドとは、
- モデルにデータが存在する場合 → true
- モデルにデータが存在する場合 → false
を返すメソッドです。
any?メソッドはモデルのデータを評価するための便利なメソッドなのでぜひ活用してみてください。
そして、any?メソッドの使い方を忘れてしまったらこの記事を確認してくださいね!