「モデルからデータを取ってきたい!」
「えーっと、find
とfind_by
とfind_by!
ってどれがどんな指定の仕方だっけ?」
「どっちを使えばいいんだっけ?」
みたいな事を覚えていなかった時に書いたメモです。
環境情報
rails (5.0.0.1)
ruby 2.3.1p112
find
特定の”ID”のレコードを1つ探す
User.find(1)
カラムを指定してデータを引っ張ってくることは出来ない(idのみ)
[24] pry(main)> User.find(email:"example@exmaple.com") User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = NULL LIMIT 1 ActiveRecord::RecordNotFound: Couldn't find User with 'id'={:email=>"example@example.com"}
複数の値を渡すこともできる(idが1と2)
User.find(1,2)
なお、指定したデータが一つでも存在しなかった場合はデータが取得できない
(下記の例はid:1は存在するがid:3は存在しない場合)
[19] pry(main)> moge = User.find(1,3) User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IN (1, 3) ActiveRecord::RecordNotFound: Couldn't find all Users with 'id': (1, 3) (found 1 results, but was looking for 2)
find_by
指定したカラムが特定の値を持つレコードを1つ探す。
User.find_by(email:"example@exmaple.com")
何もヒットしなければ nil になる
[37] pry(main)> User.find_by(email:"nodata@example.com") User Load (0.6ms) SELECT `users`.* FROM `users` WHERE `users`.`email` = 'nodata@example.com' LIMIT 1 => nil
カラム名の指定をしないとエラーになる
[36] pry(main)> User.find_by("example") User Load (2.0ms) SELECT `users`.* FROM `users` WHERE (example) LIMIT 1 ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'example' in 'where clause': SELECT `users`.* FROM `users` WHERE (example) LIMIT 1
複数のデータを取得することは出来ない。
[36] pry(main)> User.find_by(email:"example@example.com", "exmaple2@example.com") SyntaxError: unexpected ')', expecting =>
find_by!
findを使って何もヒットしなかった場合
例外(ActiveRecord::RecordNotFound)が発生する。
find_byを使って何もヒットしなかった場合
nilが返る(例外は発生しない)
find_byを使っても例外を発生させたい場合
しかし、find_byを使った場合でも例外を発生させたい場合がある。
そんな時にfind_by!を使う。find_byに「!」を付けるだけ
[38] pry(main)> User.find_by(email:"nodata@example.com") User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`email` = 'nodata@example.com' LIMIT 1 => nil [39] pry(main)> User.find_by!(email:"nodata@example.com") User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`email` = 'nodata@example.com' LIMIT 1 ActiveRecord::RecordNotFound: Couldn't find User
上記のように何もヒットしなくても例外が発生しているのが分かる。
おわり
コメント