こんにちは!oda@エンジニア1年目です!
先日、Railsで空のモデルオブジェクトを取得したいということがありました。
今日はその時に学んだことついて、書いてみようと思います。
事前準備
今回はBook
モデルを例に進めていきます。
Book
モデルには、次のデータをあらかじめ準備しています。
title | category | stock |
---|---|---|
小説1 | novel | 3 |
小説2 | novel | 2 |
マンガ1 | comic | 0 |
マンガ2 | comic | 1 |
料理1 | cooking | 2 |
料理2 | cooking | 4 |
そして、Book
モデルのレコードを全件取得しておきます。
books = Book.all
空のモデルオブジェクトを取得してみる
そもそも、空のモデルオブジェクトはnone
メソッドを使わなくても、where
メソッドを使って条件を満たすレコードがなかった時などにも返ってきます。
books.where(category: 'science') # => []
日頃、この返り値を見て「条件を満たすレコードがない時は空の配列が返ってきてるなー」と何となく思っていましたが、ここが間違いでした。
私はnone
メソッドを知る前、空のモデルオブジェクトを取得したくて以下のようなコードを書きました。
books = []
# => []
しかし、同じ返り値のように見えるこの2つには大きな違いがありました。
私がこの間違いに気がついたのは取得したbooks
に、さらにwhere
メソッドを使った時です。
違いがよくわるかようにそれぞれのbooks
のクラスも確認してみます。
books = books.where(category: 'science') # => [] books.where('stock > ?', 0) # => [] books.class # => Book::ActiveRecord_Relation
books = [] # => [] books.where('stock > ?', 0) # => undefined method `where' for []:Array (NoMethodError) books.class # => Array
RailsのActiveRecord
のメソッドであるwhere
メソッドは、Array
クラスには使えません。
そのため、空の配列をbooks
に入れると、上記のとおりNoMethodError
が発生してしまいました。
そして、空のモデルオブジェクトを取得するためにはどうしたらいいのだろうかと調べてnone
メソッドの存在を知りました。
先ほどと同じようにnone
メソッドを試すと、以下のように空のモデルオブジェクトを取得できていることが確認できます。
books = books.none # => [] books.where('stock > ?', 0) # => [] books.class # => Book::ActiveRecord_Relation
さいごに
今回の件では、none
メソッドを新たに知ることができました。
ただ、最大の収穫は新たなメソッドを知ったことではなく、返り値のクラスを常に意識しなければならないということに気がついたことです。
こういった気づきを大事にしながら、今後もレベルアップしていきたいと思います!