How to implement Rails 4 Develop a user with a company name in one nested form

I have a Rails 4 application with a simple default Devise registration flow with a user model. Now I have added a company model with a one-to-many relationship between the company and user model (the company has several users and the user belongs to the company).

I want the user to select the company name during registration, so the registration form has 3 fields: company name, user email address and password.

I get the error "Unexpected parameters: company", although I think I am solving the problem with strong parameters.

I read all the SO answers to similar questions, but none of the answers work. The following are relevant code snippets:

#routes.rb
devise_for :users, :controllers => { :invitations => 'users/invitations', 
                                      :registrations => 'users/registrations',
                                      :omniauth_callbacks => "users/omniauth_callbacks"
                                    }

resources :companies


#MODELS
#user.rb
class User < ActiveRecord::Base
  devise :invitable, :database_authenticatable, :registerable,
  :recoverable, :rememberable, :trackable, :validatable
  devise :omniauthable, :omniauth_providers => [:google_oauth2, :mailchimp, :stripe_connect, :xero]

  belongs_to :company
  accepts_nested_attributes_for :company
end

#company.rb
class Company < ActiveRecord::Base
  has_many :users
end



#CONTROLLER
#users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController 
  before_filter :configure_permitted_parameters

  def new
    build_resource({})
    self.resource.company = Company.new
    respond_with self.resource
  end

  def create
    super
  end

  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) do |u|
      u.permit(:email, :password, :password_confirmation, company_attributes: [:name])
    end
  end
end


#application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery

  def after_sign_in_path_for(resource)
    #some_path
  end
end



#VIEW
#sign up form
= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
  = devise_error_messages!
  .form-group
    = f.email_field :email, placeholder: "Email", class: "form-control"
    = hidden_field_tag "plan", params[:plan]
  .form-group
    = f.password_field :password, placeholder: "Password", class: "form-control"
  .form-group
    = f.fields_for resource.company do |cf|
      = cf.text_field :name, placeholder: "Name of your company", class: "form-control" 
  .submit= submit_tag "Sign up now", :class => "button"

The params hash is passed to Users :: RegistrationsController as follows:

{"utf8"=>"✓", "authenticity_token"=>"uWMrX3qVTLL2A1g1ONtBxuj72/GMRZqG5rcOvba/8p4=", "user"=>{"email"=>"x@foo.com", "password"=>"password", "company"=>{"name"=>"F corp"}}, "plan"=>"x", "commit"=>"Sign up now"}
+4
source share
2 answers

It seems that your disinfectant of your param is not quite right. Try the following:

def configure_permitted_parameters
  devise_parameter_sanitizer.for(:sign_up) do |u|
    u.permit(:email, :password, :password_confirmation, company: [:name])
  end
end

See the Nested Parameters section of Strong Parameters documents for more information.

+1
source

In order for it to work, you need to pluralize the "company" in the parametric filter.

u.permit(:email, :password, :password_confirmation, companies_attributes: [:name])

I had a very similar problem, and it was a solution to error errors that were not executed.

0
source

All Articles