知識ゼロからの 『とほほのRuby on Rails入門』 #おまけ
これはプログラミング初心者がRuby on Railsの勉強をしていく記録です。
◇ この記事で勉強しているサイト
◇ 前回までの記事一覧
『とほほのRuby on Rails入門』の項目は前回ですべて終わりましたが、
このままだと一度投稿したら二度と消せないコメントする人にとって大変プレッシャーがかかる仕様なので、コメントの削除をできるようにしてみました。
これをやってみて、すごく大きな学びがあったので記録しておきます!
完成したもの
そしてDeleteボタンを押すと…
これだと誰でもどのコメントでも消すことができてしまうのでほんとは良くないですが。
ユーザー設定とかまで絡めると今の私には難しすぎると思ったのでこれで大目に見てください。
コード
過程
完成したものを見ると簡単そうに見えますよね。
でもこれ4時間くらいウンウン悩んでやっと出来ました。
何が難しかったかと言うと、
Controllerのこういう記述を自分でいちから書くとなると、何を書いたらいいのかまったく分かりませんでした。
解決に至った道筋は ”ブラウザ画面から順を追って処理の流れを考える” ことでした。
ここから下の説明は結構長いですが、私はこれで “コントローラのメソッドに何を書けばいいか” という謎が解けてすごくスッキリしました。
順を追って処理の流れを考える
まずブラウザ画面のURLに”localhost:3000/“と入力すると、getメソッドで’/‘にアクセスする事になるので、home_controllerのindexメソッドが呼び出されます。
なのでコントローラのメソッド内に書くインスタンス変数は、その後呼び出されるviewに使われているものを書けばいいと言うことです!
(その事にここで気がつきました)
さらに順を追っていきます。
ブラウザ画面は今こうなっています。
「本」の文字のリンクを押すと、getメソッドで”books_path”(”/books”のこと)にアクセスします。
ここからさらに「サンプル」という文字のリンクを押すと、getメソッドで”book”(”/books/5”のこと)にアクセスします。
※”book”は”book_path(book)”の省略形で、括弧の中身だけで記載されています。
ここで変数が@bookではなくbookなのは@books.each do | book | という記述のbookというローカル変数だからだと思います。
「サンプル」というデータは:idが5なので、ここではbookという変数には:id=5という値が入っています。
下の画像にあるように、”book_path(book) “
は”/books/:id”というURLなので、”book_path(:id=5)”の場合は”/books/5”というURLを指すことになります。
ややこしいですが伝わりますかね(ーー;)
でもこの部分は以前はよくわからなかったのでやっとスッキリしました。
話は戻りますが、このルーティングによりbooks_controllerのshowメソッドが呼び出されます。
そしてここでやっと自分で記述を付け足しました。
もとは
<%= comment.commenter %>
こうだったものを、リンクをつけるためにlink_toを足し、リンク先にするパスを確かめ、
<%= link_to comment.commenter, edit_book_comment_path(comment) %>
このように変えました。
ここでもedit_book_comment_path(comment)としたのは、この記述が@book.comments.each do | comment |という記述の中にあるからです。
これで、このリンクを押すとcomments_controllerのeditメソッドが呼び出されるようになりました。
comments_controllerにeditメソッドはまだ無いので今から作ります。
このメソッド内でも特に移行先は指定しない予定なので、ブラウザ画面にはcommentsのedit.html.erbが表示されることになります。
なので、viewsのcommentsフォルダー内にedit.html.erbを新規作成します。
中の記述は作りたい内容に合わせて考えます。
今回の場合は、「コメントした人」「コメントの内容」が表示され「削除ボタン」を押せばコメントのデータが削除できる、という状態がゴールです。
そして書いたのがこれ。
Deleteボタンのパスは、これから作る予定のcomments_controllerのdestroyメソッドに繋がるように、これまたルーティング一覧(↓)から探し
deleteメソッドでbook_comment_pathにアクセスすればいけるだろうなと思ってそうしました。
そしてこのcommentsのedit.html.erbに出てくるインスタンス変数を、コントローラで記述しておいたらいいので、コントローラに書くのは
@comment = コメントに関するデータベースからid番号を指定して取り出す
という感じの記述。
そしてここはブラウザ画面のURLと見比べてみてわかったことなんですが、:book_idというのがコメントのid番号みたいです。
なので以下のように書けばOKだけど、練習コードでは2段階に分けていたので同じようにしてみました。
@comment = Book.find(params[:id]).comments.find(params[:book_id])
ここでブックのid番号も指定しないといけないのは、さっきの
このルーティングのURLに:book_id(コメントのid番号が代入される部分)と:id(ブックのid番号が代入される部分)があるからかなと思いました。
最後にdestroyメソッドを作ります。
メインとなるのは@comment.destroyです。
これを書くために、その上の2つで ”@commentとはなんぞや“ を定義しています。
そしてデータを消した後は、books_controllerのshowメソッドを呼び出して本の詳細画面に戻るようにしたかったので、redirect_to〜としてパスは下のルーティングを参考にbook_path(@book)にしています。
※ここで括弧の中を@bookにしたのは、同じメソッド内に@book = Book.find(params[:id])があるからそうしてみました。
あとがき
これで上手くいきました!!!!
出来た時はほんとーーーーに嬉しかったです。
このやり方にピンと来た時はわくわくが止まりませんでした。
そして上手くいった時は難解な問題が解けたときの気持ちよさ!!!!
またすごく成長できたような気がしています。
やってみてよかった。
文章だとだいぶ伝わりにくかったと思いますが、railsがある人は実際にブラウザ画面とファイルたちを順を追って見ていくとすごく分かりやすいと思います。おすすめです。
参照した記事たち
◇ 解決策が直接載っていたわけではないんですがこの記事たちのおかげでピンと来ました。
◇ 色々検索している時にすごくいい記事を見つけたのでご紹介。
親子関係のモデルの作り方について、すごく詳しく書いてくれています。
最後に
長文でしたがここまで読んでくださった方がいましたらありがとうございますそしてお疲れさまでした!
この記事が気に入ったらサポートをしてみませんか?