HermannHH
HermannHH

Reputation: 1772

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!

Upvotes: 0

Views: 370

Answers (1)

luissimo
luissimo

Reputation: 978

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

Upvotes: 2

Related Questions