LoginSignup
0

More than 3 years have passed since last update.

Railsアプリで編集機能を実装する

Posted at

編集機能の実装

編集機能では、既に登録された投稿の属性の値を変更してDBに保存します。
一覧画面の投稿情報ごとに「編集」リンクが表示され、そのリンクから編集画面へ遷移することにします。
また、詳細画面にも編集ボタンを設けるようにします。

編集リンクの設置

まずは一覧画面(app/views/posts/index.html.slim)に編集画面へのリンクを設置します。
編集画面はedit_post_pathというヘルパーメソッドにより、post/[投稿ID]/editというURLを生成できます。

app/views/posts/index.html.slim
h1 タスク一覧

= link_to '新規投稿', new_post_path, class: 'btn btn-primary'

.mb-3
table.table.table-hover
  thead.thead-default
    tr
      th= Post.human_attribute_name(:content)
      th= Post.human_attribute_name(:created_at)
      th
  tbody
    - @posts.each do |post|
      tr
        td= link_to post.content, post
        td= post.created_at
        td
          = link_to '編集', edit_post_path(post), class: 'btn btn-primary mr-3'

続いて、詳細画面(app/views/posts/show.html.slim)にもリンクを追加します。

app/views/posts/show.html.slim
h1 投稿の詳細

.nav.justify-content-end
  = link_to '一覧', posts_path, class: 'nav-link'
table.table.table-hover
  tbody
    tr
      th= Post.human_attribute_name(:id)
      td= @post.id
    tr
      th= Post.human_attribute_name(:content)
      td= simple_format(h(@post.content), {}, sanitize: false, wrapper_tag: "div")
    tr
      th= Post.human_attribute_name(:created_at)
      td= @post.created_at
    tr
      th= Post.human_attribute_name(:updated_at)
      td= @post.updated_at

= link_to '編集', edit_post_path, class: 'btn btn-primary mr-3'

アクションの実装

編集機能は、編集画面を表示するeditアクションと、画面から送られてきたデータを使ってDBを更新するupdateアクションの2つが必要です。
まずは、app/views/posts/edit.html.slimを以下のように編集します。

app/controllers/posts_controller.rb
def edit
  @post = Post.find(params[:id])
end

def update
  post = Post.find(params[:id])
  post.update!(post.params)
  redirect_to post_url, notice: "投稿内容を更新しました。"
end

editアクションでは、投稿データをフォーム画面で予め表示できるよう、URL内の投稿投稿IDをパラメータから受け取り、それを元にDBを検索して、編集対象のPostオブジェクトを取得し、インスタンス変数@postへ代入します。

updateアクションでは、同様に編集中のPostオブジェクトを取得し、update!メソッドによってpostパラメータの代入とDBへの保存の両方を行っています。このアクションはnewアクションとcreateアクションに似ています。

続いてビューを実装します。

app/views/posts/edit.html.slim
h1 投稿の編集

.nav.justify-content-end
  = link_to '一覧', posts_path, class: 'nav-link'

= form_with model: @post, local: true do |f|
  .form-group
    = f.label :content
    = f.text_area :content, rows: 5, class: 'form-control', id: 'post_content'
  = f.submit nil, class: 'btn btn-primary'

03CAC0F4-5709-40D9-9C76-D690744C4FE2_1_105_c.jpeg

76F4B515-DC73-49B3-BEFA-F6C52C50B4B4_1_105_c.jpeg

パーシャルを使った共通化

app/views/posts/new.html.slimファイルとapp/views/posts/edit.html.slimファイルを比べると入力フォーム部分が同じです。この同じ部分を共通化し、メンテナンスしやすくします。
共通化には、renderメソッドのパーシャルオプションを使います。
まず、パーシャルテンプレートとして、app/views/posts/_post.html.slimファイルを作ります。ファイル名の先頭にはアンダースコアをつけまが、呼び出す際はつけません。

app/views/posts/_post.html.slimに、app/views/posts/new.html.slimから、入力フォーム部分を切り取って貼り付けます。

app/views/posts/_post.html.slim
= form_with model: post, local: true do |f|
  .form-group
    = f.label :content
    = f.text_area :content, rows: 5, class: 'form-control', id: 'post_content'
  = f.submit nil, class: 'btn btn-primary'

app/views/posts/new.html.slimには、以下のように書いてapp/views/posts/_form.html.slimを呼び出します。

app/views/posts/new.html.slim
h1 つぶやきの新規投稿

.nav.justify-content-end
  = link_to '一覧', posts_path, class: 'nav-link'

= render partial: 'form', locals: {post: @post}

renderメソッドのlocalsオプションは、パーシャル内のローカル変数を設定します。locals: {post: @post}と記述すると、「インスタンス変数@postを、パーシャル内のローカル変数postとして渡す」という意味になります。これにより、ローカル変数postをパーシャル内から利用できるようになります。

app/views/posts/edit.html.slimファイルも同様に変更しておきます。

app/views/posts/edit.html.slim
h1 投稿の編集

.nav.justify-content-end
  = link_to '一覧', posts_path, class: 'nav-link'

= render partial: 'form', locals: {post: @post}

これで、編集機能の実装は完了です!

参考

現場で使える Ruby on Rails 5速習実践ガイド

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0