ruby-on-railsrubyruby-on-rails-5simple-formwicked-gem

Update many_to_many association in nested form


I have three models for the context of this question. And using the wicked gem for multi-step signup.

User

class User < ApplicationRecord
  has_one :profile
  has_many :specialties, through: :profile

  accepts_nested_attributes_for :profile, allow_destroy: true
end

Profile

class Profile < ApplicationRecord
  belongs_to :user
  has_many :profile_specialties
  has_many :specialties, through: :profile_specialties
end

Specialty

class Specialty < ApplicationRecord
  has_many :profile_specialties
  has_many :profiles, through: :profile_specialties
end

In my form, I pass specialty_ids

<%= simple_form_for @user, url: wizard_path do |f| %>

  ...

  <%= simple_fields_for :profile_attributes do |cf| %>

    <%= cf.input :specialty_ids, collection: Role.order(:name), as: :grouped_select, group_method: :specialties, input_html: {multiple: true} %>

  <% end %>

  ...

<% end %>

to the AfterSignup#update

def update
  @user = current_user
  @user.update_attributes(user_params)
  render_wizard @user
end

I believed that rails handled the update of associations through naming. But maybe I'm mistaken and need to explicitly update the associations in the controller. Or perhaps I've not named items correctly...

Either way, I'm a little unclear on why the profile specialties don't update.

Update

When I try to do a update, the console logs Unpermitted parameters: :specialty_ids

I have strong params defined as such

def user_params
  params.permit profile_attributes: [..., :specialty_ids]
end

Update 2

Here is the full log

Processing by AfterSignupController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", "profile_attributes"=>{"specialty_ids"=>["", "22"], "commit"=>"Save and Continue", "id"=>"step_one"}
  User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 52], ["LIMIT", 1]]
Unpermitted parameters: :specialty_ids
Unpermitted parameters: :utf8, :_method, :authenticity_token, :commit, :id
   (0.2ms)  BEGIN
  Profile Load (0.2ms)  SELECT  "profiles".* FROM "profiles" WHERE "profiles"."user_id" = $1 LIMIT $2  [["user_id", 52], ["LIMIT", 1]]
  SQL (0.4ms)  DELETE FROM "profiles" WHERE "profiles"."id" = $1  [["id", 110]]
  SQL (0.4ms)  INSERT INTO "profiles" ("user_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["user_id", 52], ["created_at", "2018-09-06 02:30:57.882173"], ["updated_at", "2018-09-06 02:30:57.882173"]]
   (0.5ms)  COMMIT
   (0.2ms)  BEGIN
   (0.2ms)  COMMIT
Redirected to http://localhost:3000/after_signup/requirements

Solution

  • Your strong params is expecting an array so you need:

    def user_params
      params.permit profile_attributes: [..., specialty_ids: []]
    end