RailsでviewのフォームからcontrollerにPOSTでデータを送信する
RailsのCRUDの基本のところで、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="✓" /> <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]
をそのまま使用するのはセキュリティ上よくないので、ストロングパラメータを使ってフィルタする。