はじめに
Railsアプリケーションを作成していてタスク管理アプリにラベルを紐づける実装を行う際に、confirm
からlabel_ids
パラメータをどのように渡せばいいのか迷い調べた結果を備忘録として記入します。
間違いなどがありましたらご指摘願います。
開発環境
Rails 6.0.3
Ruby 3.0.1
状況
タスク新規投稿時に事前に用意したタグを複数登録できる実装を行います。新規作成時にはconfirm
の確認画面を経由し、登録完了する流れです。
下記のようにconfirm
からパラメータを送るためhidden_field
を使用してみましたが、登録後にタスクの詳細表示をすると結果はタグが保存されていませんでした。
<h3>以下の内容で、登録します</h3>
<%= form_with(model: @task, local: true, url:tasks_path ) do |form| %>
<%= form.hidden_field :title %>
<%= form.hidden_field :content %>
<%= form.hidden_field :deadline %>
<%= form.hidden_field :status %>
<%= form.hidden_field :priority %>
<%= form.hidden_field :label_ids %>
<p>タイトル:<%= @task.title %></p>
<p>内容:<%= @task.content %></p>
<p>終了期限:<%= @task.deadline %></p>
<p>状態:<%= @task.status_i18n %></p>
<p>優先度:<%= @task.priority_i18n %></p>
<p>タグ:
<% @task.labels.each do |label|%>
<%= label.label_name %>
<% end %></p>
<%= form.submit "登録する" %>
<%= form.submit "戻る", name: 'back' %>
<% end %>
Parameters: {"authenticity_token"=>"ZA35TWGpYEUjaCITfducUU5eeigilm
PTH5sPYVC1mWq4t7iVEjLJGn9rjJ5VoEbdfeA0ozT48hl5MJcn5kp7wg==", "task"
=>{"title"=>"タスク", "content"=>"内容を入力", "deadline"=>"",
"status"=>"waiting", "priority"=>"low", "label_ids"=>"6 7 8"},
"commit"=>"登録する"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users".
"id" = $1 LIMIT $2 [["id", 25], ["LIMIT", 1]]
↳ app/helpers/sessions_helper.rb:3:in `current_user'
Unpermitted parameter: :label_ids
ターミナルでログを見るとUnpermitted parameter: :label_ids
と表示がありパラメータがconfirm
から渡せていないのだと思いました。
省略
def create
@task = current_user.tasks.build(task_params)
if params[:back]
render :new
else
if @task.save
redirect_to tasks_path, notice: "タスクを作成しました!"
else
render :new
end
end
end
省略
def confirm
@task = current_user.tasks.build(task_params)
render :new if @task.invalid?
end
省略
private
def task_params
params.require(:task).permit(:title, :content, :deadline, :status, :priority, { label_ids:[] })
end
省略
試したこと
色々調べてみるとmultiple
という属性をtrue
にすることで複数の要素を送ることができるということでしたので、multiple
をtrue
に設定し、実際にトライしてみた。
<h3>以下の内容で、登録します</h3>
<%= form_with(model: @task, local: true, url:tasks_path ) do |form| %>
<%= form.hidden_field :title %>
<%= form.hidden_field :content %>
<%= form.hidden_field :deadline %>
<%= form.hidden_field :status %>
<%= form.hidden_field :priority %>
<%= form.hidden_field :label_ids, multiple: true %>
<p>タイトル:<%= @task.title %></p>
<p>内容:<%= @task.content %></p>
<p>終了期限:<%= @task.deadline %></p>
<p>状態:<%= @task.status_i18n %></p>
<p>優先度:<%= @task.priority_i18n %></p>
<p>タグ:
<% @task.labels.each do |label|%>
<%= label.label_name %>
<% end %></p>
<%= form.submit "登録する" %>
<%= form.submit "戻る", name: 'back' %>
<% end %>
今度はタグが最初の一つは登録されたが、test_02
とtest_03
のタグが送られていないため保存できていないようでした。
Parameters: {"authenticity_token"=>"nXNVarxEXEWUUHm1UVH7AS4JLKiEvWDzGb941uqIWdFByRSyz9/1GshT1zh5KiGNHbdiI5LT8Tl/FOCQXHe7eQ==", "task"=>{"title"=>"タスク", "content"=>"内容を入力", "deadline"=>"2022-07-13", "status"=>"waiting", "priority"=>"low", "label_ids"=>["6 7 8"]}, "commit"=>"登録する"}
省略
Task Create (0.8ms) INSERT INTO "tasks" ("title", "content",
"created_at", "updated_at", "deadline", "priority", "user_id")
VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["title",
"タスク"], ["content", "内容を入力"], ["created_at", "2022-07-13
11:48:15.113828"], ["updated_at", "2022-07-13 11:48:15.113828"],
["deadline", "2022-07-13"], ["priority", 2], ["user_id", 25]]
↳ app/controllers/tasks_controller.rb:29:in `create'
Labelling Create (0.6ms) INSERT INTO "labellings" ("task_id",
"label_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4)
RETURNING "id" [["task_id", 19], ["label_id", 6], ["created_at",
"2022-07-13 11:48:15.118759"], ["updated_at", "2022-07-13
11:48:15.118759"]]
↳ app/controllers/tasks_controller.rb:29:in `create'
(1.9ms) COMMIT
↳ app/controllers/tasks_controller.rb:29:in `create'
Redirected to http://localhost:3000/tasks
結果
更に調べてみるとmultiple属性をtrue
にすると、配列が変更され、最初に選択されたラベルだけが保存されるようになってしまうとのことで、each
を使って繰り返し行う方法に辿り着き実践してみました。
<h3>以下の内容で、登録します</h3>
<%= form_with(model: @task, local: true, url:tasks_path ) do |form| %>
<%= form.hidden_field :title %>
<%= form.hidden_field :content %>
<%= form.hidden_field :deadline %>
<%= form.hidden_field :status %>
<%= form.hidden_field :priority %>
<% @task.labels.each do |label| %>
<%= form.hidden_field :label_ids, multiple: true, value: label.id %>
<% end %>
<p>タイトル:<%= @task.title %></p>
<p>内容:<%= @task.content %></p>
<p>終了期限:<%= @task.deadline %></p>
<p>状態:<%= @task.status_i18n %></p>
<p>優先度:<%= @task.priority_i18n %></p>
<p>タグ:
<% @task.labels.each do |label| %>
<%= label.label_name %>
<% end %></p>
<%= form.submit "登録する" %>
<%= form.submit "戻る", name: 'back' %>
<% end %>
最後に
今回、なかなかラベル機能の複数のパラメータをhidden_filed
で送る方法を見つけることができなかったので、同じことで悩まれている方の参考になればと思いました。間違っている点やもっと良い方法があるのかもしれませんが、その際はご指摘願います。
ありがとうございました。