Herm Herm - 3 months ago 22
Ruby Question

Nesting Parent Company in devise sign up form using Rails

I want to structure my app that a User belongs to a company and that a Company can have many users. The company name should be included in the my Devise Sign Up form.

Here is my code:

company.rb

class Company < ApplicationRecord
has_many :users
end


user.rb

class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
belongs_to :company
accepts_nested_attributes_for :company
end


registrations_controller.rb

class RegistrationsController < Devise::RegistrationsController

before_action :configure_sign_up_params, only: [:create]

# GET /resource/sign_up
def new
build_resource({})
set_minimum_password_length
resource.build_company
yield resource if block_given?
respond_with self.resource
end

# POST /resource
def create
build_resource(sign_up_params)
resource.save
if resource.persisted?
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_flashing_format?
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
set_minimum_password_length
respond_with resource, location: new_api_v1_public_members_user_registration_path(beta_token: params[:beta_token])
end
end

def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up) do |user_params|
user_params.permit(:email, :password, :password_confirmation, company: [ :name])
end
end
end


_form.haml

...
= f.text_field :email
= f.fields_for :company do |c|
= c.text_field :name
= f.password_field :password, autocomplete: "off", autofocus: true
= f.password_field :password_confirmation, autocomplete: "off"
...


Using the code given above, submits all the values to my create route (as per my log file). The Company parent value however is not being persisted. This causes my form validation to fail as the Company.name value cannot be blank.

How do I change this code to:


  1. Save the Parent (Company) that is nested in the Child (User) form

  2. Assign the Company.id value to the User when it is saved by populating the 'company_id' attribute in the User model



Any help is appreciated!

Answer

Try changing

  def configure_sign_up_params
    devise_parameter_sanitizer.permit(:sign_up) do |user_params|
      user_params.permit(:email, :password, :password_confirmation, company: [ :name])
    end
  end

To

  def configure_sign_up_params
    devise_parameter_sanitizer.permit(:sign_up) do |user_params|
      user_params.permit(:email, :password, :password_confirmation, company_attributes: [:id, :name, :_destroy])
    end
  end

And in your user.rb model change ; accepts_nested_attributes_for :company to

accepts_nested_attributes_for :company, reject_if: :all_blank, allow_destroy: true

And i don't know how HAML works but i see no end for the f.fields_for block.

  = f.fields_for :company do |c|
  = c.text_field :name
  = end