Ruby on Rails5 Progate Ⅳ サイト利用者が投稿編集
投稿詳細ページに「編集」,「削除」項目を追加して実行できる様にする
データベースを操作して編集、削除ができる様にする
〜投稿の編集〜
rails consoleで ①編集したい投稿を取得
②その投稿のcontentの値を上書き
③データベースに保存
$rails console
$ post = Post.find_by(id :1) //①
$ post.content = "上書き" //②
$ post.save //③
〜投稿の削除〜
rails consoleで
①編集したい投稿を取得
②destroyメソッドで削除
$rails console
$ post = Post.find_by(id :1) //①
$ post.destroy //②
・投稿編集ページを用意
・投稿編集ページへのリンクを作成
どの投稿を編集するか判断するために、
投稿編集ページのURLには編集する投稿ページのidを入れたい
ルーティングに:idを含んで編集ページをidで指定
[routes.rb]
get "posts/:id/edit" => "post#edit"
//localhot:3000/posts/1/edit 等のURLに対応する
postsコントローラ内にeditアクションを作り、
対応するビュー(edit.html.erbファイル)も作成する
[controller.rb]
def edit
end
投稿編集ページへのリンク追加
[show.html.erb] //投稿詳細ページ
<%= link_to("編集", "/posts/#{@post.id}/edit") %>
〜入力フォームの用意〜
投稿内容をフォームの初期値にする
①editアクションでURLと同じidの投稿データをDBから取得
②contentの値を <textarea> に表示される初期値に設定
①
[posts_controller.rb]
def edit
@post.find_by(id: params[:id])
end
②
[edit.html.erb]
<teatarea><%= @post.content %></textarea>
編集内容を保存する準備
・編集フォームの入力内容を受け取るアクションの作成
・そのアクションにリンクするルーティングの作成
・内容を受け取るアクションなのでhtmlは作成せず、保存に成功したらredirectで一覧に戻す様にする
updeteアクションの用意
新規投稿の際に作成したcreateアクションと同じ様な役割のアクション
今回は updateアクション
特定の投稿のデータを送信するのでルーティングにURLから投稿のidを含む
機能
・フォームの内容の保存
・投稿一覧画面への転送
updeateアクションのルーティング
フォームの値を受け取るのでルーティングをpostにする
フォームの送信先指定(新規投稿ページ作成時と同様)
編集ページのビューにform_tagメソッドを使用
フォームの入力内容をupdateアクションに送信する(ルートの指定と一緒)
[routes.rb]
post "posts/:id/update" => "posts#update"
[posts_controller.rb]
def update
@post = Post.find_by(id: params[:id])
@post.content = params[:content]
@post.save
redirect_to("/posts/index")
end
[edit.html.erb]
<%= form_tag("/posts/#{@post.id}/uptdate" do)%>
<textarea = "content"><% @post.content %></textarea>
<input type="submit" value="保存">
<% end %>
編集ページでの入力内容の反映
<textarea>タグにname属性を指定することで、フォームの入力内容が変数paramsに代入されてupdateアクションに送信される
updateアクションでは、フォームから送信された値をparams[:content]で
受け取り、@post.content = params[:content]で投稿データの内容を更新
[controller.rb]
def update
@post = Post.find_by(id: params[:id])
@post.content = params[:content] //フォームの値の受け取り
@post.save
end
[edit.html.erb]
<%= form_tag("/posts/#{@post.id}/update") do%> //データベースのidを取得して送信先指定
<textarea nama="content"></textarea> //name属性の指定
<% end %>
〜削除機能の追加(destroyアクション)〜
[routes.rb]
post "posts/:id/destroy" => "posts#destroy"
[controller.rb]
@post = Post.find_by(id: params[:id])
@post.destroy
redirect_to("/posts/index")
[show.html.erb]
<%= link_to("削除", "/posts/#{@post.id}/destroy"),{method:"post"} %>
destroyアクションのルーティング
post "posts/:id/destroy" => "posts#destroy"
(URLから削除したい投稿を特定できる様にURLからidを取得 )
get と post の使い分け
・get = データベースを変更しないアクション
・post = データベースを変更するアクション
投稿編集ページからのdestroyアクションへのリンク作成
<%= link_to("削除" , "/posts/#{@post.id}/destroy", {method:"post"}) %>
普通のlink_toメソッドだとgetのアクションにしかアクセスできない。
postのルーティングにリンクさせたい場合はlink_to(〜)の 第三引数にに{method:"post"}をつける