Railsの存在確認メソッド 使い分けメモ　(any?/empty?/present?(!blank?)/nil?)

# はじめに
Railsのビューで、「画像があったら表示させる」みたいな処理を書く場面がありました。
存在確認のためのメソッドは、Rubyのもの、Railsのもの含め、いくつかあります。
ちょっと調べて、「よし、これで行こう！」とメソッドを選択してレビューに出したところ、おもいっきり玉砕したので、今後間違えないように備忘録として残しておきます。

# 環境
macOS Catalina Version 10.15.5
Ruby: 2.6.5
Ruby on Rails: 6.0.3

# 調査対象
- any?(Ruby)
- empty?(Ruby)
- nil?(Ruby)
- present?(Rails)

#動機
過去にも類似の記事はあり、実際に大部分、「[rubyの真偽判定メソッド(nil?/empty?/blank?/present?)を検証してみた結果、興味深いことがわかった](https://qiita.com/go_d_eye_0505/items/541110cb9821734b0623)」に乗っからせていただきました。そのうえで、今回投稿に至った理由は、以下となります。

- 上記投稿においてany?メソッドが触れられていなかったが、any?の挙動についても確認したかった（今回直面したのが、配列絡みの問題だったため）
- 上記投稿のまとめの表では、<br>　-「**ある** かどうかを聞くメソッド（present?等。何かあればtrueを返す）」<br>　-「**無い** かどうかを聞くメソッド（empty?等。何も無ければtrueを返す）」<br>が並べて表記されていたが、「何かある場合に〇〇を返す」というように、条件の方向を揃えた表（present?と not empty?が比較できるような表）が欲しかった<br>※もちろん上記の表のメリットとして、present?とblank?が裏の関係になっていることがわかりやすい、等があります

なお、blank？は除外しています（present?の定義が!blank?のため）。

# 調査方法
rails consoleを使います。

```
test = XXX ←ここに色々代入していく

test.any?
!test.empty?
test.present?
!test.nil?
```

# 調査結果

|   | any? | !empty?<br>(empty?の否定)| present?<br>(!blank?)|!nil?<br>(nil?の否定)| 
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| Ruby/Rails  | Ruby  | Ruby | Rails | Ruby | 
|1<br>数字|NoMethodError| NoMethodError|<font color="ForestGreen">true</font>|<font color="ForestGreen">true</font>|
|"foo"<br>文字列|NoMethodError|<font color="ForestGreen">true</font>|<font color="ForestGreen">true</font>|<font color="ForestGreen">true</font>|
|{key: value}<br>ハッシュ|<font color="ForestGreen">true</font>|<font color="ForestGreen">true</font>|<font color="ForestGreen">true</font>|<font color="ForestGreen">true</font>|
|["foo"]<br>配列|<font color="ForestGreen">true</font>|<font color="ForestGreen">true</font>|<font color="ForestGreen">true</font>|<font color="ForestGreen">true</font>|
|true|NoMethodError|NoMethodError|<font color="ForestGreen">true</font>|<font color="ForestGreen">true</font>|
|false|NoMethodError|NoMethodError|<font color="Red">false</font>|<font color="ForestGreen">true</font>|
|nil|NoMethodError|NoMethodError|<font color="Red">false</font>|<font color="Red">false</font>|
|""<br>空|NoMethodError|<font color="Red">false</font>|<font color="Red">false</font>|<font color="ForestGreen">true</font>|
|" "<br>半角スペース|NoMethodError|<font color="ForestGreen">***TRUE***</font>|<font color="Red">***FALSE***</font>|<font color="ForestGreen">true</font>|
|{}<br>空ハッシュ|<font color="Red">false</font>|<font color="Red">false</font>|<font color="Red">false</font>|<font color="ForestGreen">true</font>|
|[]<br>空配列|<font color="Red">false</font>|<font color="Red">false</font>|<font color="Red">false</font>|<font color="ForestGreen">true</font>|
|[nil]<br>配列(要素がnil)|<font color="Red">***FALSE***</font>|<font color="ForestGreen">***TRUE***</font>|<font color="ForestGreen">***TRUE***</font>|<font color="ForestGreen">***TRUE***</font>|
※ `any?`はEnumerableモジュールで定義されているため、配列やハッシュ以外で使おうとしてもNoMethodErrorとなります

### 要点

この結果から今後気を付けなきゃなと思ったところは、表内で大文字で強調していますが、改めて以下に記載しておきます。

1. 半角スペースは、`!empty?`では~~存在するもの~~**空ではない**とみなされtrueを返し、`present?`では空とみなされfalseを返す<br>
   ↑（修正）@scivola 様よりコメントをいただき、修正および追記しました。ありがとうございました。<br>
　（追記）`present?`（もとい`blank?`）は、空判定の出る範囲が広めであることに注意<br>
　　　　　例：false、nil、半角スペース以外に、全角スペース、タブ(\t)、改行(\n)、Unicode(\unnnn)等も空と判定される
2. 配列に`any?`を適用すると、**真の要素(＝nilでない要素)**がある場合にtrueを返す。それ以外のメソッドは、真か否かに関係なく、要素があればtrueを返す。
3. 素の `nil`に`!nil?`って聞いてもfalseを返すが、 `[nil]`でできた配列に`!nil?`と聞くとtrueを返す


### その他
Railsで、`exists?`というメソッドもあります。これは、データベースに特定の条件のデータが存在するか確かめるときに使うようで、`ActiveRecord::Base`で定義されているメソッドとのことでした。そのことをつゆ知らず、当初調査対象に含めていましたが、すべて`NoMethodError`を返されました。


# 学び
Qiita初投稿となりました。シンプルでごく当たり前の内容だとは思いますが、アウトプットのために調べる、整理する、といった過程を通じて理解を深める良い機会となりました。
定期的に、今後の自分(≒他人)にとって役に立つ記事を投稿していきたいと思います。


# 参考URL
[rubyの真偽判定メソッド(nil?/empty?/blank?/present?)を検証してみた結果、興味深いことがわかった](https://qiita.com/go_d_eye_0505/items/541110cb9821734b0623 "rubyの真偽判定メソッド(nil?/empty?/blank?/present?)を検証してみた結果、興味深いことがわかった")