o..o
o..o

Reputation: 1921

Devise registration for with nested entity

I'm building a Rails app where User can have more Addresses.

User has_many :addresses
Address belong_to :user

I'm using Devise for authentication. I want an User entity and first Address entity to be created by one form when the user is registering.

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= f.email_field :email %><br />
  <%= t.password_field :password %><br />

  <%= f.fields_for resource.addresses do |a| %>
    <%= a.text_field :street %>
  <% end %>
<% end %>

But I'm getting

undefined method 'street' for ActiveRecord::Associations::CollectionProxy []

what must be done in controller?

Thanks

EDIT

I have already in the User model:

accepts_nested_attributes_for :addresses

And I have updated my controller like this:

class Users::RegistrationsController < Devise::RegistrationsController

  # GET /resource/sign_up
  def new
    # super
    build_resource({})
    yield resource if block_given?
    resource.addresses.build
    respond_with resource
  end
end

and view:

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= f.email_field :email %><br />
  <%= t.password_field :password %><br />

  <%= f.fields_for resource.addresses.first do |a| %>
  <%= a.text_field :street %>
<% end %>

So the form is displaying. But when I post, the resource.addresses.first is still null:

undefined method `model_name' for nil:NilClass

Thanks

Upvotes: 0

Views: 217

Answers (1)

Bala Karthik
Bala Karthik

Reputation: 1413

You need to add accepts_nested_attributes_for addresses

Class User < ActiveRecord::Base
  has_many :addresses
  accepts_nested_attributes_for :addresses
end

You also need to initialise the address object, You can do this at controller level (Best Approach) or at view

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= f.email_field :email %><br />
  <%= t.password_field :password %><br />
  <% resource.addresses.build %>
  <%= f.fields_for resource.addresses do |a| %>
    <%= a.text_field :street %>
  <% end %>
<% end %>

And you need to add the corresponding to the parameters that you are receiving at your controller.

Upvotes: 1

Related Questions