Search code examples
ruby-on-railsnested-attributesruby-on-rails-5

Cannot get a nested model to save in rails 5


I have a user which is a nested resource of account, and I'm trying to create the account and the user in 1 form. The account is saving correctly, however no user record is being written.

user.rb:

class User < ApplicationRecord
  belongs_to :account
  validates :email, presence: true
end

account.rb:

class Account < ApplicationRecord
  has_many :users, :dependent => :destroy
  accepts_nested_attributes_for :users
end

accounts_controller.rb:

class AccountsController < ApplicationController
  def new
    @account = Account.new
    @user = @account.users.build
  end

  def create
    @account = Account.new(account_params)
    @account.secret = SecureRandom.uuid
    if @account.save
      flash[:success] = "You've successfully created your account, now it's time to create your first team."
      redirect_to dashboard_path
    else
      flash[:danger] = "There was a problem creating your account"
      redirect_to signup_path
    end
  end

  private

    def account_params
      params.require(:account).permit(:name, user_attributes: [:first_name, :last_name, :email, :password, :password_confirmation, :secret])
    end
end

accounts/new.html.erb:

<h1>Signup</h1>
<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@account) do |form| %>
      <%= form.label "Account name" %>
      <%= form.text_field :name, class: "form-control" %>

      <%= form.fields_for :user do | f| %>
        <%= f.label :first_name %>
        <%= f.text_field :first_name, class: "form-control" %>

        <%= f.label :last_name %>
        <%= f.text_field :last_name, class: "form-control" %>

        <%= f.label :email %>
        <%= f.text_field :email, class: "form-control" %>

        <%= f.label :password %>
        <%= f.password_field :password, class: "form-control" %>

        <%= f.label :password_confirmation, "Confirmation" %>
        <%= f.password_field :password_confirmation, class: "form-control" %>
      <% end %>

      <%= form.submit "Signup", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

When I submit the the form and check my logs, I'm seeing:

Processing by AccountsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"p5+CRICRp3ZilIg1NtehEQG7Gh2amnFFUD5NawtqkICJ4uRDvvJxf2WTbd7+rnfG9zdblT1QWgfJ62NNxcc2RA==", "account"=>{"name"=>"Streame", "user"=>{"first_name"=>"Jeremy", "last_name"=>"Kirkham", "email"=>"jeremy@streame.com.au", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}, "commit"=>"Signup"}
Unpermitted parameter: user

Solution

  • The answer was quite simple in the end - I needed to change the form from

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

    to

    <%= form.fields_for :users do | f| %>

    (note user -> users), and the controller from

    params.require(:account).permit(:name, user_attributes:

    to

    params.require(:account).permit(:name, users_attributes:

    (again note user -> users).

    Basically it came down to pluralisation!