Models
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :roles, :dependent => :destroy, :inverse_of => :user
has_many :companies, :through => :roles
accepts_nested_attributes_for :roles, :limit => 1, :allow_destroy => true
end
class Role < ActiveRecord::Base
belongs_to :user, :inverse_of => :roles
belongs_to :company, :inverse_of => :roles
accepts_nested_attributes_for :company
end
class Company < ActiveRecord::Base
has_many :roles, :dependent => :destroy, :inverse_of => :user
has_many :users, :through => :roles
validates :name, presence: true
end
Custom Devise Registration Controller
class RegistrationsController < Devise::RegistrationsController
# GET /resource/sign_up
def new
build_resource({})
@role = resource.roles.build(role: "owner", active: 1, default_role: 1)
@company = @role.build_company
set_minimum_password_length
yield resource if block_given?
respond_with self.resource
end
protected
def sign_up_params
params.require(:user).permit(:email, :password, :password_confirmation, roles_attributes: [ company_attributes: [ :id, :name ] ] )
end
end
HTML
<%= form_for(resource, :html => {:class => "form-signin" }, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render partial: "shared/flash" %>
<%= devise_error_messages! %>
<h1 class="form-signin-heading text-muted">Register</h1>
<%= f.email_field :email, class: "form-control", placeholder: "Email", autofocus: true %>
<%= f.password_field :password, class: "form-control", placeholder: "Password", autocomplete: "off" %>
<%= f.password_field :password_confirmation, class: "form-control", placeholder: "Password Confirmation", autocomplete: "off" %>
<%= f.fields_for :roles, resource.roles.build do |r| %>
<%= r.fields_for :company, resource.roles.build.build_company do |c| %>
<%= c.text_field :name, class: "form-control", placeholder: "Company", autocomplete: "off" %>
<% end %>
<% end %>
<button class="btn btn-lg btn-primary btn-block" type="submit">
Register
</button>
<% end %>
This works - my intermediate Role is created with the id_user and id_company. The problem is I want to set the some additional fields in the newly created Role. for example I have a :role column that I want to set to 'owner' as this is the a brand new company and the user that signed up is the owner.
I want to do this in the controller to prevent any mass assignment issues from the user submitted form.
Do I need to set this somehow in the custom devise registration controller and create a full custom create action?
I admit I am likely not explaining this well as I am a bit of a newbie on the whole nested forms and active record etc.
UPDATE
It's not pretty but I just pasted this at the end of my new controller:
def set_minimum_password_length
if devise_mapping.validatable?
@minimum_password_length = resource_class.password_length.min
end
end
UPDATE 2
I had copied the master code vs the current version code. Once I fixed that it's all good.