Search code examples
ruby-on-railsruby-on-rails-4nested-formsnested-attributes

nested attributes and form not saving Rails 4


I am trying to nest a user to an account and allow the user to be created when the account is created. I am having an issue when creating both the account and user from the same form, and my server output is not very helpful in trying to isolate the problem.

here is the output when I try to save the Account and User.

Started POST "/accounts" for ::1 at 2016-10-10 20:55:23 -0600
Processing by AccountsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"UK7h4edNzRomi7JGomoZD1ayYmlNxI/h2ZH+NEaJxWQzcFsYAJujr5EDDS2HeprAX41IuS5/crRxmXYz80YpYw==", "account"=>{"subdomain"=>"mydomain", "owner_attributes"=>{"email"=>"swilson@ta#####td.com", "f_name"=>"S####", "l_name"=>"W####", "date_of_birth"=>"19##-##-##", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}, "commit"=>"Create Account"}
   (0.3ms)  BEGIN
  User Exists (0.3ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2  [["email", "swilson@ta#####td.com"], ["LIMIT", 1]]
  Account Exists (0.3ms)  SELECT  1 AS one FROM "accounts" WHERE "accounts"."subdomain" IS NULL LIMIT $1  [["LIMIT", 1]]
   (0.2ms)  ROLLBACK
  Rendering accounts/new.html.erb within layouts/application
  Rendered accounts/_form.html.erb (3.8ms)
  Rendered accounts/new.html.erb within layouts/application (5.1ms)
  Rendered shared/_signed_out_nav.html.erb (1.3ms)
Completed 200 OK in 183ms (Views: 44.2ms | ActiveRecord: 1.1ms)

I believe the issue may have something to do with the account generation and the subdomain. but I Can not pin it down for the life of me!

also I commented out my personal info with the ####...

here is my account controller

class AccountsController < ApplicationController

  def new
    @account = Account.new
    @account.build_owner
  end

  def create
    @account = Account.new(account_params)
    respond_to do |format|
      if @account.save
        format.html {redirect_to root_path, notice: 'Account successfully created.'}
      else
        format.html {render :new, alert: 'There was a problem, please try again.'}
      end
    end
  end

  private

  def account_params
    params.require(:account).permit(:subdomain, owner_attributes: [:email, :password, :password_confirmation, :f_name, :l_name, :date_of_birth])
  end

  def set_account
    @account = Account.find(params[:id])
  end

end

here is my account form:

<%= bootstrap_form_for(@account) do |f| %>
  <div class="row">
    <div class="col-xs-12">
      <%= f.text_field :subdomain, hide_label: true, placeholder: 'Company Name', append: ".patrolvault.net" %>
    </div>
  </div>

  <%= f.fields_for :owner do |o| %>
    <div class="row">
      <div class="col-xs-12">
        <%= o.email_field :email, label: 'Email Address' %>
      </div>
      <div class="col-xs-12">
        <%= o.text_field :f_name, label: 'First Name' %>
      </div>
      <div class="col-xs-12">
        <%= o.text_field :l_name, label: 'Last Name' %>
      </div>
      <div class="col-xs-12">
        <%= o.date_field :date_of_birth, label: 'Date Of Birth' %>
      </div>
      <div class="col-xs-6">
        <%= o.password_field :password, label: 'Password' %>
      </div>
      <div class="col-xs-6">
        <%= o.password_field :password_confirmation, label: 'Confirm Password' %>
      </div>
    </div>
  <% end %>

  <%= f.submit :class => 'btn btn-primary' %>
<% end %>

and here is my account model:

class Account < ApplicationRecord
  # Before Actions
  before_validation :downcase_subdomain

  # Relationships
  belongs_to :owner, class_name: 'User', optional: true 
  accepts_nested_attributes_for :owner

  # Validations
  validates :owner, presence: true

  RESTRICTED_SUBDOMAINS = %w(www, patrolvault, test)
  validates :subdomain, presence: true,
                        uniqueness: { case_sensitive: false },
                        format: { with: /\A[\w\-]+\Z/i, message: 'Contains invalid characters.' },
                        exclusion: { in: RESTRICTED_SUBDOMAINS, message: 'Restricted domain name'}

  # Custom Methods

  private

  def downcase_subdomain
    self.subdomain = subdomain.try(:subdomain)
  end

end

Please let me know if you require further info or if I have missed something! Thanks!


Solution

  • so the problem was in my before_validation :downcase_subdomain. once I removed that and the matching method everything began to work fine. I will rework this.

    Thanks.