LoginSignup
10
12

More than 5 years have passed since last update.

【Rails】findとfind_byの違い

Posted at

findとfind_by

findメソッド  ・・・idを元にデータベースから該当のデータをひとつ引っ張ってくる
find_byメソッド・・・id以外の項目でもデータベースから該当のデータをひとつ引っ張ってくる

rails.console
[1] pry(main)> User.find(1)
id:〜
name:〜
email:〜
〜
〜

[2] pry(main)> User.find_by(1)
id:〜
name:〜
email:〜
〜
〜

検索結果が見つからなかった場合の返り値の違い

findメソッド ・・・エラーが返ってくる
find_byメソッド・・・nilが返ってくる

rails.console
[3] pry(main)> User.find(3)
  User Load (0.5ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1
ActiveRecord::RecordNotFound: Couldn't find User with 'id'=3
from /Users/moritasatoshi/.rvm/gems/ruby-2.5.0/gems/activerecord-5.2.1/lib/active_record/core.rb:177:in `find'


[4] pry(main)> User.find_by_id(3)
  User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1
=> nil

条件分岐処理時のnilの扱われ方

Railsでは、nilが返ってきた際の条件分岐の処理は必ずfalseにて処理されます。
そのため、下記のような記述の際にエラーの見せ方が変わってきます。

@userをfindと、find_byメソッドで探してきて、見つかった場合と見つからなかった場合でエラーメッセージを返す条件分岐を記述しました。

users_controller.rb
  def show
    @user = User.find(params[:id])
    if @user
    else
      render json: { error: 'Faild find user'}, status: 422
    end
  end

findメソッドの場合、@user = User.find(params[:id]の返り値でエラーが吐かれてしまうため、
下に記述したelseの内容が処理されず404エラーが返ってしまいます。

users_controller.rb
  def show
    @user = User.find_by(id: params[:id])
    if @user
    else
      render json: { error: 'Faild find user'}, status: 422
    end
  end

処理としては似ている記述ですが、条件分岐のelseの記述を活かすには、返り値がnilとなるfind_byメソッドを使用しましょう。

検証

ターミナル上で、存在しないidにて検索を試してみました。

$ curl http://localhost:3000/api/users/3
{"error":"Failed find user"}

elseに記述したエラーメッセージを確認できました。

今日はこのあたりで失礼します。

参考サイト

【Rails初心者必見!】ひたすら丁寧にデータ取得を説明(find, where)
https://qiita.com/mr-myself/items/cfb936dcf63d2c44d2f5

10
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
12