みやちゃ
どうもこんにちは!みやちゃです!
物理とプログラミングを学ぶ大学生です!
Railsで1からサービスを作ってブログにほぼ毎日投稿してます!
このサイトは、「昔の私」も一緒に見ています。
「昔の私」は少しでも疑問に感じたらすぐ登場します。
「昔の私」と一緒に勉強しましょう!
昔の私
よろしくお願いします!
何もわからないよ!
・edit/updateアクションをControllerに定義
・editのViewを作成
・実際に投稿(Postモデル)の編集/更新
モデル(Model)の編集・更新方法ってどうするのかわからない。。
教材をコピペして一応機能はできたけど、それらのコードの意味がわからない。。
この記事では、どうコードを書くのかだけではなく、コードが何を意味しているのかも詳しく解説しています!
・edit/updateアクションのController・View・ルーティングが、意味を理解した上で書けるようになります!
以下のような流れで進めていきます!
1、edit/updateアクションのそれぞれの役割とは?
2、editアクションをControllerに定義/edit.html.erb(View)の作成/editアクションのルーティングの設定
3、updateアクションのControllerに定義/updateアクションのルーティングの設定
目次
edit/updateアクションの役割
直訳すると、editアクションは「編集」、updateアクションは「更新」ですね。
では具体的にはそれぞれのアクションで何をしているのでしょうか?
editアクションは、編集するモデルを特定し、編集された内容を受け取り、updateアクションに内容を送信します。
updateアクションは、editアクションから受け取った内容を元にデータベースを書き換えます。
実際にコードを書いて見ましょう!
editアクションをControllerに定義
posts_controller.rbを開き、以下のようにコードを書きます。
def edit
@post = Post.find(params[:id])
end
昔の私
@post??
先頭に「@」がつく変数は、インスタンス変数と言います!
インスタンス変数は、同じクラス内であれば、メソッドを抜け出しても使うことができます!
この後のViewのところでやりますが、Controllerのeditメソッドを抜け出して、editのViewへデータを受け渡すことができます!
昔の私
find??
findメソッドは、idによってモデルを検索してくれるメソッドです!
例えば、Post.find(1)とすれば、"id = 1"のPostモデルを探してくれるのです!
Terminalで「rails c」を実行して、確かめてみましょう!
昔の私
params[:id]??
paramsメソッドは、送信された値の受け渡しをするメソッドです!
params[:カラム]のように書いて、モデルのカラムを指定してあげることで、送信された値のパラメータからその値を取り出してくれます。
今回は、params[:id]としているので、idカラムを取り出してくれています!
つまり、Post.find(params[:id])は、
送信されたパラメータの中からidカラムを取り出し、そのidをもとにPostモデルを探しているのですね!
Viewの作成
みやちゃ
Controllerにeditアクションを定義できましたね!
次に、Viewを作成していきましょう!
Viewには、編集内容を入力するためのフォームを書いていきます。
view/postsフォルダに新たに「edit.html.erb」という名前のファイルを作成します。
edit.html.erbを開き、以下のように記述します。
<h1>投稿を編集</h1>
<%= form_with(model: @post, local: true) do |form| %>
<div>
<%= form.label :title, "タイトル" %>
<%= form.text_field :title %>
</div>
<div>
<%= form.label :body, "内容" %>
<%= form.text_area :body %>
</div>
<div>
<%= form.submit "投稿を更新", data: { confirm: '上記の内容で投稿を更新します。よろしいですか?' } %>
</div>
<% end %>
昔の私
form_with??
local: true??
何が何だか全然わからない。。
みやちゃ
form_withの書き方は,こちらの記事「form_withの使い方」で詳しく解説しています!
ここではかなり長くなってしまうので、かいつまんで話していきます!
form_withとは
form_withとは、フォーム作成を支援するヘルパーです!
このform_withを使うことによって、簡単にフォームを作成することができます。
<h1>投稿を編集</h1>
<%= form_with(model: @post, local: true) do |form| %>
<div>
<%= form.label :title, "タイトル" %>
<%= form.text_field :title %>
</div>
<div>
<%= form.label :body, "内容" %>
<%= form.text_area :body %>
</div>
<div>
<%= form.submit "投稿を更新", data: { confirm: '上記の内容で投稿を更新します。よろしいですか?' } %>
</div>
<% end %>
・form_with(model: @post)の部分は、どのモデルを編集するかを、model: @postを引数として渡してあげることで、指定しています!
・local: trueは、form_withのデフォルトである非同期通信でデータを送信するのをキャンセルしています!
・labelは、入力するフォームの名前を指定できます!
・text_fieldは、1行のみの入力フォームを作成します!
・text_areaは、複数行入力可能な入力フォームを作成します!
・submitは、上で入力されたデータを送信先に送信します!
・date: {confirm: }を指定することで、ボタンを押した時にメッセージが出力されるようになります!
かなり省略してしまいました。。。
・どんな感じでメッセージが出るの??
・特に「update」って指定してないけどちゃんとupdateアクションに送信されるの??
これらの疑問も上で紹介したこちらの記事「form_withの使い方」できっと解決できると思います!
editのルーティング設定
みやちゃ
Viewの作成ができましたね!
次にルーティングの設定をしていきましょう!
ルーティングは、URLを指定してあげることで、Controller内の適切なアクションに割り当てることができます!
ルーティングは、routes.rbで記述します!
configフォルダにあるroutes.rbを開き、以下のように記述します。
get 'posts/:id/edit', to: 'posts#edit', as: 'edit_post'
上記のように記述することで、posts/:id/editというリクエスト(URL)を送信した時に、編集画面が出てくるようになります!
みやちゃ
試しに、localhost:3000/posts/1/editにアクセスしてみましょう!
うまく表示できました!
昔の私
get??
GETは、HTTPメソッドの1つです!
HTTPメソッドには、GET、POST、PUT、DELETE、PATCHがあります。
これらのHTTPメソッドには、それぞれに役割・特徴があります。
GETは、「データを取得する」時に使われます!
editアクションでは、idで指定されたPostモデルの内容を編集するために、そのPostモデルのデータを取得して、Viewに表示させたいので、GETを使いました!
昔の私
'posts/:id/edit'??
これはリクエスト(URL)を指定しています!
「"posts/:id/edit"というリクエストがあったら、〜〜を実行しなさい」という意味です!
昔の私
to: 'posts#edit'??
これは実行するControllerのメソッドを指定しています!
「posts#edit」は、「PostsControllerのeditメソッドを実行しなさい」という意味です!
昔の私
as: 'edit_post'??
これは、そのメソッドのパスに名前を指定しています!
「edit_post」と指定しているので、「edit_post_path」としてあげれば、editのページを呼び出すことができます!
昔の私
パス??
パス(path)は、特定のメソッドの位置を示すものです!
例えば、「edit_post_path」は、「PostsControllerのeditメソッド」を示しています。
みやちゃ
ルーティングの設定ができましたね!
昔の私
「投稿を更新」のボタンを押して更新しようとしたら、
エラーが出ちゃったーー
みやちゃ
あとで詳しく解説しますが、このエラーは、
[PATCH]"/posts/1"なんてURLは設定されていない!という意味です。
updateアクションの定義を何もしていないので当然ですね!
まずは、updateアクションを定義しましょう!
updateアクションをControllerに定義
posts_controller.rbを開き、以下のようにコードを書きます。
def update
@post = Post.find(params[:id])
@post = @post.update(post_params)
redirect_to posts_path
end
#以下の「post_params」は、new/createの時に定義済み
def post_params
params.require(:post).permit(:body, :title)
end
先ほどもしたように、@postにidで指定したPostモデルを格納してますね!
そして、updateメソッドを使って、編集内容を更新しています!
昔の私
「@post.update(post_params)」って、なんか右に()がついてる。。
これは引数です!
updateアクションでは、データベースを更新します。
更新をするために必要なデータ(カラムの情報)を引数として渡しているのです!
引数の「post_params」は、別で定義されています。
昔の私
params.require().permit()??
先頭から見てみましょう!
paramsメソッドは、送信されてきた値の受け渡しをするメソッドです!
require/permitメソッドは、ストロングパラメータというやつです!
requireメソッドでは、パラメータ群を指定しています!
permitメソッドでは、どのパラメータを許可するかを指定しています!
ストロングパラメータとは、require/permitメソッドによって、送信されるパラメータが安全かどうかを検証した上で、それらの情報を取得することを言います!
昔の私
「redirect_to posts_path」??
redirect_toを使えば、自動的に指定したページに移動してくれます!
「posts_path」は、indexのページなので、Postモデルの更新が完了したら、投稿一覧ページに自動で移動してくれます!
みやちゃ
updateアクションをControllerに定義できましたね!
次は、updateアクションのルーティングを設定しましょう!
updateのルーティング設定
みやちゃ
先ほど出た「Routing Error」がここで解決しますね!
routes.rbを開き、以下のようにコードを書いてください。
patch 'posts/:id', to: 'posts#update'
みやちゃ
先ほどやったeditのルーティング設定と同様に説明していきます!
・PATCHは、HTTPメソッドの1つです!
これらのHTTPメソッドには、GET、POST、PUT、DELETE、PATCHがあります。
これらのHTTPメソッドには、それぞれ役割・特徴があります。
PATCHは、「情報を更新する」時に使われます!
updateアクションでは、idで指定されたPostモデルの情報を更新するので、PATCHを使いました!
・posts/:idは、リクエスト(URL)を指定しています!
・to: 'posts#update'は、実行するControllerのメソッドを指定しています!
「posts#update」は、「PostsControllerのupdateメソッドを実行しなさい」という意味です!
みやちゃ
updateのルーティング設定ができましたね!
きっと先ほどのエラーはもう出ないでしょう!
先ほどのエラー画面を更新してみましょう!
うまく一覧画面に移動してますね!
まとめ
みやちゃ
お疲れ様でした!
いかがでしたでしょうか!
これでedit/updateアクションは、意味を理解した上でコードを書けるようになると思います!
長い間「昔の私」にお付き合いいただきありがとうございます!
みやちゃ
最後までご覧いただきありがとうございました!