質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.05%

  • Ruby

    6142questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails 5

    642questions

ルーティングで設定したURLの「:id」について

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 118

uraura

score 3

Ruby on Rails 5 でアプリケーションを作成しております。

書類の名前が並んだ一覧表ページ(index)から、名前をクリックすると編集ページ(edit)に遷移するようにしました。編集ページのURLはルーティングで以下のように設定してあります。

edit_document GET    /documents/:id/edit(.:format)      documents#edit

ページの遷移はうまくいきます。
例えばIDが18の書類の名前をクリックすると、URLは /documents/18/edit となるのですが、編集ページで表示される書類の名前が全く違うIDのものになってしまいます。

確認のためコントローラを以下のように書いてみたところ、params[:id]は18でしたが、@document.idが16と食い違って出力されました。

documents_controller.rb

def edit
    @document = Document.find_by(params[:id])
    puts params[:id]  #=> 18
    puts @document.id   #=> 16
end


食い違うのはなぜなのでしょうか?

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

こんにちは

@document = Document.find_by(params[:id])


の find_by を、find にして、

@document = Document.find(params[:id])


と修正するとうまくいきませんか?

参考になれば幸いです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/14 08:23

    回答ありがとうございます!
    アドバイス通り、find_byをfindにしたらうまくいきました! findとfind_byの違いについて調べたところ、* 該当するレコードがない場合の挙動の違い
    * findはidしか検索しない
    ということがわかりましが、以前はfind_byできちんと通っていたのに今回はfindでなくてはいけないのはどうしてなのでしょうか?引き続きご回答いただけると幸いです。

    キャンセル

  • 2018/01/14 09:17 編集

    rails c
    で、rails コンソールを起動して、
    Document.find_by(18)
    とすると、
    SELECT "documents".* FROM "documents" WHERE (18) LIMIT 1
    というクエリが発行されているのを確認できると思います。
    このクエリだと、たぶん id の一番小さいレコードが返ってくるものとは
    思いますが、SQL の文法的には、どの1レコードが返ってくるかは
    予測できないです。

    こういう条件なら、find_by でもうまくいっているように見えてしまう、
    ということで考えられることは以下です。

    もし、documentsテーブルのレコードが1つしかなくて、
    それの id が、仮にたとえば 10 だったとしましょう。
    そのとき
    Document.find_by(10) は
    SELECT "documents".* FROM "documents" WHERE (10) LIMIT 1
    となって、これが、たまたまその1つしかない id=10 のレコードを返しますので、
    /documents/10/edit
    というパスで入力編集画面のテストをしていたすると、
    ちゃんと find_by が id=10 のレコードを探してきて表示させている
    ように見えてしまいます。

    ということで、find_by でうまくいっているように見えていた間は、
    documentsに1つしかレコードがない状態で、
    edit画面(または他の画面)を表示させていた、ということは
    ないでしょうか?

    キャンセル

  • 2018/01/15 09:24

    大変丁寧な回答ありがとうございます。
    Document.find_by(18)
    ですと、
    ArgumentError: Unsupported argument type: 17 (Integer)
    となってしまいました。

    >たぶん id の一番小さいレコードが返ってくるものとは思いますが
    この点はおっしゃられる通りで、レコードが3つ(id: 16, 17, 18)の時は find_by(params[:id])で一番小さいレコード id: 16 の名前が出力されていました。

    >find_by でうまくいっているように見えていた間は、documentsに1つしかレコードがない状態で
    ちょっと記憶が曖昧なのですが確かにそうかもしれません・・・!

    find_byを使うときはfind_by(id: params[:id])のように、idを検索することを明示的にすると問題ないようです。今後はfindかfind_byか、違いをもう一度おさらいしてどちらを使うか決めたいと思います。

    ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.05%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Ruby

    6142questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails 5

    642questions