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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

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

Q&A

解決済

1回答

937閲覧

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

uraura

総合スコア11

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

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

0グッド

1クリップ

投稿2018/01/13 15:03

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは

ruby

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

find_by を、find にして、

ruby

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

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

参考になれば幸いです。

投稿2018/01/13 15:21

編集2018/01/13 15:53
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uraura

2018/01/13 23:23

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

2018/01/14 00: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画面(または他の画面)を表示させていた、ということは ないでしょうか?
uraura

2018/01/15 00: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か、違いをもう一度おさらいしてどちらを使うか決めたいと思います。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問