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"}をつける






いいなと思ったら応援しよう!