dev/mom0tomo

技術メモ

RailsでviewのフォームからcontrollerにPOSTでデータを送信する

RailsCRUDの基本のところで、newアクションからcreateアクションにデータを送るあたりがよくわからなくなったのでまとめる。

学んだ事

formタグのPOSTメソッドとパラメータの関係

まずはRailsではなく素のHTMLで考える。

<form action="/" method="POST">
  <label>名前: <input type="text" name="target_name"></label>
  <input type="submit" value="送信">
</form>

viewにこのようなフォームがある場合、

  • ユーザからのアクションは全て、HTTPリクエストのGETメソッドやPOSTメソッドとしてWebサーバに送信される。
  • HTTPリクエストのPOSTメソッドで送ったデータは、params(パラメータ)に格納される。
  • Webサーバはリクエストをもとに、paramsに入っているユーザからのデータを処理し、レスポンスを返す。

これが基本。


Railsのnewアクション

app/controller/task_controller

class TasksController < ApplicationController
  before_action :set_task, only: [:show, :edit, :update, :destroy]

  def index
    @tasks = Task.all
  end

  def show
  end

  def new
    @task = Task.new
  end
end

newアクションでは、対応するviewをPOST メソッドを送信する新規作成用の入力フォーム置き場として使う。

app/views/messages/new.html.erb

<h1>タスク新規作成ページ</h1>

<%= form_for(@task) do |f| %>
  <%= f.label :content, 'タスク' %>
  <%= f.text_field :content %>

  <%= f.submit '登録' %>
<% end %>

<%= link_to '一覧に戻る', messages_path %>

上のようなviewを書く事で、POSTメソッドを使ったフォームが生成される。

<body>
  <div class="container">
    <h1>新規タスク作成</h1>
    <form class="new_task" id="new_task" action="/tasks" accept-charset="UTF-8" method="post"> // POSTメソッドを使う
      <input name="utf8" type="hidden" value="&#x2713;" />
      <input type="hidden" name="authenticity_token" value="1XF/tmSKY6ak0LovbntLa/AqaxPSPAG6Ak5YyBdA4W3ebzM8KilBV+Vxw5adGwhqPE7pEJ9mn3ZbgJdGKQsJ1w==" />
      <label for="task_content">タスク</label>
      <input type="text" name="task[content]" id="task_content" />
      <input type="submit" name="commit" value="登録" data-disable-with="登録" />
    </form>
    <a href="/tasks">一覧に戻る</a>
  </div>
</body>

viewから実際に生成されるHTMLはこんな感じになる。

Railsのcreate アクション

app/controller/task_controller

class TasksController < ApplicationController

....

  def new
    @task = Task.new
  end

  def create
    @task = Task.new(task_params)
  
    respond_to do |wants|
      if @task.save
        flash[:success] = 'Taskが登録されました'
        redirect_to @message
      else
        flash.now[:danger] = 'Taskが登録されませんでした'
        render :new
      end
    end
  end

  private

    def set_task
      @task = Task.find(params[:id])
    end

    # ストロングパラメータ
    def task_params
      params.require(:task).permit(:content)
    end
end

create アクションは、newのviewからPOSTで送信されたフォームのデータを処理する。

new からcreateへ送られてきたフォームの内容は params[:task] に入る。
params[:task] をそのまま使用するのはセキュリティ上よくないので、ストロングパラメータを使ってフィルタする。