views:

33

answers:

1

*Note to view all code, follow the link

I am creating new "accounts". Each new Account have_many :users. Users have_and_belong_to_many roles. I am trying to assign EXISTING roles to new users, in the new account form. Typically an easy process however...

The have_and_belong_to_many association between Users and Roles implies that users and roles are associated by a join table. I don't have a model to work with. So I am not sure how to go about coding this. I'm able to create new Roles, using methods outlined here (in the answer) but I am clueless as to assign existing Roles to new users through the account model.

The SQl equivalent would be something like this: SQL (0.1ms) INSERT INTO "roles_users" ("role_id", "user_id") VALUES (6, 29)Where I need 29 to function like the ID of the new user created in rails i.e. VAULES (6, ID)

Current Code: (creates a new role)

<% f.fields_for :users do |builder| %>
<%= render 'user_fields', :f => builder %>
<p>Login  : <%= f.text_field :login %>
<p>Email  : <%= f.text_field :email %>
<p>Password  : <%= f.password_field :password %>
<p>Confirm Password  : <%= f.password_field :password_confirmation %>
<%= f.hidden_field :account_id, :value => :id %>


<% f.fields_for :roles do |builder| %>
     <%= builder.hidden_field :name, :value => 'test' %>
<% end %>

Account.rb

has_many :users
accepts_nested_attributes_for :users

User.rb

has_and_belongs_to_many :roles
accepts_nested_attributes_for :roles

accounts_controller.rb

def new
    @account = Account.new
    #builds user and roles in memory
    1.times do
      user =  @account.users.build 
    1.times { user.roles.build }
  end
+1  A: 

The problem is you're using accepts_nested_fields for when you shouldn't be. It's used to create and destroy items of the referenced model from the calling model. You want to manage the associations, from the user model, not the roles themselves.

Here's what's got to be done:

  1. remove accepts_nested_attributes_for :roles from user.rb (optional, but recommended)
  2. Assign to role_ids field in the user creation form.

This view should illustrated the point:

<% f.fields_for :users do |builder| %>
<p>Login  : <%= f.text_field :login %>
<p>Email  : <%= f.text_field :email %>
<p>Password  : <%= f.password_field :password %>
<p>Confirm Password  : <%= f.password_field :password_confirmation %>
<%= f.hidden_field :account_id, :value => :id %>

<%= f.collection_select :role_ids, Role.all, :id, :name, {}, :multiple => true %>

<% end %>

Without changing anything else, Rails will populate the join model on create instead of modifying existing Roles or creating new ones.

EmFi
Can I send you a starbucks giftcard? I've been working on this problem all day. Thank you!
JZ