noname
noname

Reputation: 565

Rails5. Nested attributes are not going to database

class User < ApplicationRecord
  has_one :address
  accepts_nested_attributes_for :address
end

class Address < ApplicationRecord
  belongs_to :user
end

<%= form_for @user do |f| %>
  .... // some filed here everything fine
  <%= f.fields_for :address do |a| %>
     <%= a.text_field :city %> // this field is not appear
  <% end %>
<% end %>

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.valid?
      @user.save
    else
      redirect_to root_path
    end
  end

  private
    def user_params
      params.require(:user).permit(:id, :name, :email, :password, :password_confirmation, :status, :image, :address_attributes => [:id, :city, :street, :home_number, :post_code, :country])
    end
end

So like you can see above I have two classes and one form, when I am trying display fields for Address class I can not do it in that way. I took this example from https://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for I was trying different combination like for example using User.new and Address.new in form definition it not working as well, I was able display all fields in that situation but I wasn't able to save Address data to table, because of "unpermited address".

Can someone explain what I am doing wrong? Or at least give me please some hints.

[SOLVED] I should learn how to read documentations properly. Excalty like @Srack said I needed just use build_address method. I checked documentation rails api again and on the end of page there was examples says to create User class like this:

class User < ApplicationRecord
  has_one :address
  accepts_nested_attributes_for :address
  def address
    super || build_address
  end
end

and that solved my issue.

Thank you.

Upvotes: 2

Views: 61

Answers (1)

SRack
SRack

Reputation: 12203

You'll have to make sure there's an address instantiated for the user in the new view. You could do something like:

def new
  @user = User.new
  @user.build_address
end

You should then see the address fields on the form.

The nested_fields_for show the fields for a record that's been initialised and belong to the parent. I think the latter is why your previous attempts haven't worked.

FYI build_address is an method generated by the belongs_to association: http://guides.rubyonrails.org/association_basics.html#methods-added-by-belongs-to

Upvotes: 3

Related Questions