0

Is it possible to set an additional attribute on the join model when using accepts_nested_attributes_for?

I have User, Account, and Role models. The Account model accepts nested properties for users. This way users can create their account and user records at the same time.

class AccountsController < ApplicationController
  def new
    @account = Account.new
    @user = @account.users.build
  end
end

The above will work, but the user.roles.type defaults to member. At the time of registration, I need user.roles.type to default to admin. This does not work:

class AccountsController < ApplicationController
  def new
    @account = Account.new
    @role = @account.role.build
    # Role.type is protected; assign manually
    @role.type = "admin"
    @user = @account.users.build
  end
end

Accounts#new

<%= simple_form_for(@account, html: { class: 'form-horizontal' }) do |f| %>
  <legend>Account Details</legend>
  <%= render 'account_fields', f: f %>

  <%= f.simple_fields_for :users do |user_form| %>
    <legend>Personal Details</legend>
    <%= render 'users/user_fields', f: user_form %>
  <% end %>

  <%= f.submit t('views.accounts.post.create'), class: 'btn btn-large btn-primary' %>
<% end %>

Models:

class User < ActiveRecord::Base
  has_many :roles
  has_many :accounts, through: :roles
end

class Account < ActiveRecord::Base
  has_many :roles
  has_many :users, through: :roles
  accepts_nested_attributes_for :users
end

# user_id, account_id, type [admin|moderator|member]
class Role < ActiveRecord::Base
  belongs_to :user
  belongs_to :account
  after_initialize :init

  ROLES = %w[owner admin moderator member]

  private
  def init
    self.type = "member" if self.new_record?
  end
end

Inheritance could solve this issue but I find it complicates things. I need roles to be dynamic so users can add their own admins and mods, and so on. I think I'm running into these issues because I'm not modeling my data modeling correctly.

Mohamad
  • 34,731
  • 32
  • 140
  • 219

1 Answers1

0

You could change your model to initialize the type to "admin" instead of "member".

private
def init
  self.type = "admin" if self.new_record?
end
Yosep Kim
  • 2,931
  • 22
  • 23
  • I prefer not to do this, since the only time the record needs to be "admin" is at the time of registration. Most other instances it will be different. I keep thinking I'm not modeling my data correctly. – Mohamad May 01 '12 at 20:18