6
5

More than 1 year has passed since last update.

Railsで新規作成/編集の確認画面を作る

Posted at

はじめに

確認画面の情報は既にいくつも公開されていますが、編集の際の確認画面に関しては、あまり見当たらなかったため記事にしました。

開発環境

  • Rails 6.0.3.1
  • Ruby 2.6.8

やりたいこと

既に新規登録/編集機能があるアプリにて、それぞれ投稿の前に確認画面を挟みたい。
今回は、titlecontentというカラムを持つBlogモデルに関して実装していく。

新規投稿の確認画面

Controllerの実装

新規投稿の際のcontrollerは以下のようになります。

blog_controller.rb
    def new
        @blog = Blog.new
    end

    def confirm
        @blog = Blog.new(blog_params)
        render :new if @blog.invalid?
    end

    def create
        @blog = Blog.new(blog_params)

        if params[:back] || !@blog.save
            render :new
        else
            redirect_to blogs_url, notice: "#{@blog.title}を投稿しました。"
        end
    end

newcreateアクションは、Railsのチュートリアル等のまんまです。
追加点として、
1. confirmアクションを定義し、内部で値が不正だったら、newにレンダリングする
2. createアクションでは、params[:back]という値があるとき、もしくはblogが保存できなかったとき、newにレンダリング、そうでない時は一覧画面へリダイレクトする。この時のparams[:back]は後ほど、view側で設定。
の上記2点です。

Viewの実装

ビューでは新しくapp/views/blogs/confirm.html.erbを作成します。
中身は、ブログの各カラムが確認できるshowのようなものと、投稿/修正するボタンを含めたフォームになっています。

confirm.html.erb

<h1>
  <%= @blog.title %>
</h1>

<p>
  <%= @blog.content %>
</p>

<%= form_with model: @blog, local: true do |f| %>
  <%= f.hidden_field :title %>
  <%= f.hidden_field :content %>
  <%= f.submit "投稿する" %>
  <%= f.submit "修正する", name: "back" %>
<% end %>

ポイントとしては、
1. 修正に戻るsubmitボタンに、name属性としてbackを指定する
2. title, contentをhidden_fieldとしてユーザーから編集できない形で再度サーバー側に送るようにする
の2点です。確認画面から編集内容をサーバーに送る方法としては、hidden_fieldで値を隠す方法、sessionを用いる方法の2つが挙げられますが、パスワードや管理者権限等の値を取り扱っていないため、今回はhidden_fieldを用いています。
sessionを用いる方法に関しては、こちらのサイトなどをご参考ください。

続いて、app/views/blogs/new.html.erbのformの送り先もconfirmに設定し直します。

new.html.erb
<%= form_with model: @blog, url: confirm_blogs_url(@blog), local: true do |f| %>
  <div>
    <%= f.label :title %>
    <%= f.text_field :title %>
  </div>
  <div>
    <%= f.label :content %>
    <%= f.text_area :content %>
  </div>
  <%= f.submit "投稿する" %>
<% end %>

formタグのurlにて、送り先が変更されている点にご注意ください。

routes.rbの編集

最後に、ルーティングを設定して、実装完了です。
ルーティングは、resourcesを用いている場合は、以下のようになります。

routes.rb
  resources 'blogs' do
    collection do
      post 'confirm'
    end
  end

編集の確認画面

ここまでで新規投稿の確認画面に関して、実装してきましたが、ここから編集の確認画面を実装していきます。
と言っても、被っている点が非常に多いので、説明は簡潔にしていきたいと思います。

Controllerの実装

blogs_controller.rb
    def edit
        @blog = Blog.find(params[:id])
    end

    def edit_confirm
        @blog = Blog.find(params[:id])
        @blog.attributes = blog_params
        render :edit if @blog.invalid?
    end

    def update
        @blog = Blog.find(params[:id])
        if params[:back] || !@blog.update(blog_params)
            render 'edit'
        else
            redirect_to blogs_url, notice: "#{@blog.title}を編集しました。"
        end
    end

ほとんど新規投稿の際のアクションと同様ですが、attributesメソッドを用いて、値の更新をしていることにご注意ください。また、編集の性質上、idが必要なため新規投稿と編集でconfirmを違うアクションとして設定しています。

Viewの実装

Viewもほとんど新規投稿と同じです。

edit_confirm.html.erb

<h1>
  <%= @blog.title %>
</h1>

<p>
  <%= @blog.content %>
</p>

<%= form_with model: @blog, local: true do |f| %>
  <%= f.hidden_field :title %>
  <%= f.hidden_field :content %>
  <%= f.submit "投稿する" %>
  <%= f.submit "修正する", name: "back" %>
<% end %>

edit.html.erb
<%= form_with model: @blog, url: edit_confirm_blog_url(@blog), local: true do |f| %>
  <div>
    <%= f.label :title %>
    <%= f.text_field :title %>
  </div>
  <div>
    <%= f.label :content %>
    <%= f.text_area :content %>
  </div>
  <%= f.submit "投稿する" %>
<% end %>

urlの違いにご注意ください。

routes.rbの編集

最後に、ルーティングを設定して、実装完了です。
編集の際にはidが必要なため、memberの中に追加します。

routes.rb
  resources 'blogs' do
    collection do
      post 'confirm'
    end
    member do
      patch 'edit_confirm'
    end
  end

参考記事に関して

公式ガイド等の他に以下の記事を参考に、執筆させていただきました。
- 【Ruby on Rails】確認画面を作る方法!hiddenか?セッションか?
- rails で確認画面作成

6
5
0

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
6
5