27
12

More than 1 year has passed since last update.

【Rails初心者】 XXX_idsのhidden_fieldを使ったパラメータの渡し方で躓いた件

Last updated at Posted at 2022-07-13

はじめに

Railsアプリケーションを作成していてタスク管理アプリにラベルを紐づける実装を行う際に、confirmからlabel_idsパラメータをどのように渡せばいいのか迷い調べた結果を備忘録として記入します。
間違いなどがありましたらご指摘願います。

開発環境

Rails 6.0.3
Ruby 3.0.1

状況

タスク新規投稿時に事前に用意したタグを複数登録できる実装を行います。新規作成時にはconfirmの確認画面を経由し、登録完了する流れです。
下記のようにconfirmからパラメータを送るためhidden_fieldを使用してみましたが、登録後にタスクの詳細表示をすると結果はタグが保存されていませんでした。

app/views/tasks/confirm.html.erb
<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 %>

INKU6k5YXihYFC3g57Ob1657679114-1657679195.gif

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から渡せていないのだと思いました。

app/controllers/tasks_controller.rb
省略
  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にすることで複数の要素を送ることができるということでしたので、multipletrueに設定し、実際にトライしてみた。

app/views/tasks/confirm.html.erb
<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 %>

02.gif
今度はタグが最初の一つは登録されたが、test_02test_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を使って繰り返し行う方法に辿り着き実践してみました。

app/views/tasks/confirm.html.erb
<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 %>

03.gif
なんとか思い通りの実装ができました。

最後に

今回、なかなかラベル機能の複数のパラメータをhidden_filedで送る方法を見つけることができなかったので、同じことで悩まれている方の参考になればと思いました。間違っている点やもっと良い方法があるのかもしれませんが、その際はご指摘願います。
ありがとうございました。

27
12
2

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
27
12