0
votes

I'm building a user management system, and I'm starting off with a device for authentication.

The system will allow users to have their own profile, as well as profiles for dependents (children). What I am envisioning is that when the users create their account, they are added to the users table (by the device) with the basic email/password fields. I also want the users to have a profile in a seperate Profile model. The thing that is different about my approach from other questions I have seen on StackOverflow is that I want to have a has_many relationship, :through a relationship table. Here's why.

Every user will have a profile, their own. Each user should be able to create profiles for their children, and have those profiles associated with their user account. Children will not have their own user models. Therefore, each user could have multiple profiles. I would also like to do this through a relationship table. Later down the road, if a user's spouse joins the system, I would like to be able to associate children to both parents.

user.rb

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :id, :email, :password, :password_confirmation, :remember_me

  has_many :relationships

  has_many :profiles, :through => :relationships
  accepts_nested_attributes_for :profiles

  attr_accessible :profiles, :profiles_attributes
end

profile.rb

class Profile < ActiveRecord::Base
  attr_accessible :first_name, :last_name

  has_many :relationships
  has_many :users, :through => :relationships
end

relationship.rb

# Had to enter at least 6 characters to improve post (formatting was flawed)
class Relationship < ActiveRecord::Base
  attr_accessible :first_name, :last_name

  has_one :relationship_type

  belongs_to :user
  belongs_to :profile
end

new.html.erb

<h2>Sign Up for your account</h2>

<%= form_for(resource,  :as => resource_name, 
                        :url => registration_path(resource_name)) do |f| %>

  <%= devise_error_messages! %>

  <div>
    <%= f.label :email %><br />
    <%= f.email_field :email, :autofocus => true %>
  </div>

  <div>
    <%= f.label :password %><br />
    <%= f.password_field :password %>
  </div>

  <div>
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation %>
  </div>

  <%= f.fields_for :profile do |builder| %>
    <div>
      <%= builder.label :first_name %><br />
      <%= builder.text_field :first_name %>
    </div>

    <div>
      <%= builder.label :last_name %><br />
      <%= builder.text_field :last_name %>
    </div>
  <% end %>

  <div><%= f.submit "Sign up" %></div>
<% end %>

<%= render "devise/shared/links" %>

When browsing to the sign_up page, the form loads correctly. On trying to save a new user, though.. I get the following error.

Can't mass-assign protected attributes: profile

In the new.html.erb, I have tried changing the line for the nested form to

<%= f.fields_for :profiles do |builder| %>

but that just caused the nested form to not get rendered.

I would appreciate any help!

Thanks!

1

1 Answers

0
votes

:profiles, not :profile

<%= f.fields_for :profiles do |builder| %>
<div>
  <%= builder.label :first_name %><br />
  <%= builder.text_field :first_name %>
</div>

<div>
  <%= builder.label :last_name %><br />
  <%= builder.text_field :last_name %>
</div>

And you will need to build a profile in the controller:

resource.profiles.build