Search code examples
ruby-on-railsdevisesimple-formnested-forms

Rails 5 Simpleform not updating nested attributes


Sorry I've looked at similar questions to this but still can't figure it out for some reason...

I'm using Devise and I'm trying to update my User model and a City model at the same time (through the edit registrations page) using a nested form.

I'm updating the users city based on a set of predefined values that are in the database. So all the user has to do is select a city they are living in from a list and then it save.

All that happens at the moment is the form submits but the city isn't changed.

Thanks in advance!

#user.rb
class User < ApplicationRecord
  belongs_to :city
end

#city.rb
class City < ApplicationRecord
  has_many :users
end

My Controller:

class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])

    if @user.update(user_params)
      redirect_to @user
    else
      render 'edit'
    end
  end

  def show
    @user = User.find(params[:id])
  end

  private

  def user_params
    params.require(:user).permit(city_attributes: [:id, :name, :user_id])
  end
end

And my form:

<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>

      <%= f.simple_fields_for :city do |c| %>

      <%= c.input :city_id, collection: City.all.order(name: :asc), label_method: :name, value_method: :id, label: "City", include_blank: false, selected: @user.city_id %>

      <% end %>
<% end %>

Solution

  • Okay so I sorted my problem out based on the comment from Iceman and response from ajerferson.

    (However the issue that the nested form doesnt work still remains, but my issue is fixed)

    As Iceman said Devise was permitting its own parameters in my application controller. So I moved the parameters there (instead of changing my routes).

    # application_controller.rb
    def configure_permitted_parameters
        devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name])
        devise_parameter_sanitizer.permit(:account_update, keys: [:first_name, :last_name, :date_of_birth, :gender, city_attributes: [:id, :name, :user_id]])
      end
    

    I tried again but the same problems were occuring. So what I did was actually scrap the nested form and simply change my application controller to this and targetting the city_id foreign key:

    def configure_permitted_parameters
        devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name])
        devise_parameter_sanitizer.permit(:account_update, keys: [:first_name, :last_name, :date_of_birth, :gender, :city_id])
      end
    

    My form:

    <%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
    
      <%= f.input :city_id, collection: City.all.order(name: :asc), label: "City" %>
    
    <%= f.button :submit, "Save" %>
    <% end %>
    

    and now it works perfectly fine!