0

I have a form that collects company information as well as the first user (the company admin). When I submit the form, the company attributes are saved to the db. However, the user attributes are not. I get the error Unpermitted parameters: user. I can't figure out why the user is not being created and saved.

I have:

class CompaniesController < ApplicationController

  def new
    @company = Company.new
    @plans = Plan.all
  end

  def create
    @company = Company.new(company_params)

    @user = User.new
    @user.role = "admin"
    @user.save

    if @company.save
      redirect_to @company, notice: 'Company was successfully created.'
    else
     render action: 'new'
    end
  end

  private
    # Never trust parameters from the scary internet, only allow the white list through.
    def company_params
      params.require(:company).permit(:name, :plan_id, users_attributes: [:id, :company_id, :email, :password, :password_confirmation, :first_name, :last_name, :role, :rate])
    end
end

and

class UsersController < ApplicationController

#  include UsersHelper

  def index
    @users = User.all
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    @user.save
    flash.notice = "User '#{@user.first_name} #{@user.last_name}' was successfully created."
    redirect_to user_path(@user)
  end

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

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

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

    flash.notice = "User '#{@user.first_name}' has been updated."
    redirect_to user_path(@user)
  end

  def destroy
  end

  private
    # Never trust parameters from the scary internet, only allow the white list through.
    def user_params
      params.require(:user).permit(:email, :password, :password_confirmation, :first_name, :last_name, :role, :rate)
    end

end

and

class Company < ActiveRecord::Base
  has_many :users
  belongs_to :plan
  accepts_nested_attributes_for :users, :allow_destroy => true
end

and

class User < ActiveRecord::Base

  authenticates_with_sorcery!
  validates_confirmation_of :password, message: "should match confirmation", if: :password
  has_many :jobs
  belongs_to :company

end

and

<%= form_for(@company) do |f| %>
  <% if @company.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@company.errors.count, "error") %> prohibited this company from being saved:</h2>

      <ul>
      <% @company.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name, :id => "name" %>
  </div>
  <div class="field">
    <%= collection_select( :company, :plan_id, @plans, :id, :name ) %>
  </div>
  <%= f.fields_for :user do |user| %>
  <div class="field">
    <%= user.label :email %><br>
    <%= user.text_field :email %>
  </div>
  <div class="field">
    <%= user.label :password %><br>
    <%= user.password_field :password %>
  </div>
  <div class="field">
    <%= user.label :password_confirmation %><br>
    <%= user.password_field :password_confirmation %>
  </div>
  <div class="field">
    <%= user.label :first_name %><br>
    <%= user.text_field :first_name %>
  </div>
  <div class="field">
    <%= user.label :last_name %><br>
    <%= user.text_field :last_name %>
  </div>
  <div class="field">
    <%= user.label :role %><br>
    <%= user.text_field :role %>
  </div>
    <% end %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

and

ActiveRecord::Schema.define(version: 20140421235514) do

  create_table "companies", force: true do |t|
    t.string   "name"
    t.string   "stripe_token"
    t.integer  "plan_id"
    t.integer  "user_id",      limit: 255
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "companies", ["plan_id"], name: "index_companies_on_plan_id"
  add_index "companies", ["user_id"], name: "index_companies_on_user_id"

  create_table "plans", force: true do |t|
    t.string   "stripe_id"
    t.string   "name"
    t.integer  "amount"
    t.string   "interval"
    t.string   "currency"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "users", force: true do |t|
    t.string   "email",                           null: false
    t.string   "crypted_password",                null: false
    t.string   "salt",                            null: false
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "reset_password_token"
    t.datetime "reset_password_token_expires_at"
    t.datetime "reset_password_email_sent_at"
    t.string   "first_name"
    t.string   "last_name"
    t.string   "role"
    t.integer  "rate"
    t.integer  "company_id"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token"

end

2 Answers 2

1

Company and User are associated with 1-M Relationship , i.e., Company has_many :users

In that case, in your view for Company, the nested form should be

<%= f.fields_for :users do |user| %>  ## Notice users in plural

and NOT

<%= f.fields_for :user do |user| %>

Refer to the Nested Attributes Examples for One to Many

Currently, fields_for is setup incorrectly with singular :user so in params hash you got the key as :user and again a warning Unpermitted parameters: user because of which the user attributes were not stored in database.

Now, as you have setup accepts_nested_attributes_for in Company model. Controller is expecting user attributes in key users_attributes within params hash.

Changing the fields_for with plural :users argument would result in creation of users_attributes key in params hash upon form submission.

UPDATE

Company has many users, its 1-M relationship Only users table should have foreign key as company_id. You need to remove user_id from companies table.

Also, update the CompaniesController#new action as below:

def new 
  @company = Company.new 
  @users = @company.users.build 
  @plans = Plan.all 
end
Sign up to request clarification or add additional context in comments.

4 Comments

I actually tried that. When I change it to :users the nested form fields disappear from the page.
Make sure you have fields_for within <%= %> and not <% %>. They would only disappear if they are not rendered.
I do. The only thing I did was to make the key plural. I have the same code as I do in the question.
Kirti spent so much time with me in her chat room to get this resolved. She's so awesome!
0

Strong params permitting looks fine to me but i think the issue is in the nested form, you used wrong relation name user while its users which generates a params hash titled with user which is not permitted, instead you should do:

<%= f.fields_for :users do |user| %>
  #rest of the form elements
<% end %>

1 Comment

See my comment above please.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.