Override devise registrations controller
In your form are you passing in any other attributes, via mass assignment that don't belong to your user model, or any of the nested models?
If so, I believe the ActiveRecord::UnknownAttributeError is triggered in this instance.
Otherwise, I think you can just create your own controller, by generating something like this:
# app/controllers/registrations_controller.rbclass RegistrationsController < Devise::RegistrationsController def new super end def create # add custom create logic here end def update super endend
And then tell devise to use that controller instead of the default with:
# app/config/routes.rbdevise_for :users, :controllers => {:registrations => "registrations"}
A better and more organized way of overriding Devise controllers and views using namespaces:
Create the following folders:
app/controllers/my_deviseapp/views/my_devise
Put all controllers that you want to override into app/controllers/my_devise and add MyDevise
namespace to controller class names. Registrations
example:
# app/controllers/my_devise/registrations_controller.rbclass MyDevise::RegistrationsController < Devise::RegistrationsController ... def create # add custom create logic here end ... end
Change your routes accordingly:
devise_for :users, :controllers => { :registrations => 'my_devise/registrations', # ... }
Copy all required views into app/views/my_devise
from Devise gem folder or use rails generate devise:views
, delete the views you are not overriding and rename devise
folder to my_devise
.
This way you will have everything neatly organized in two folders.
I believe there is a better solution than rewrite the RegistrationsController. I did exactly the same thing (I just have Organization instead of Company).
If you set properly your nested form, at model and view level, everything works like a charm.
My User model:
class User < ActiveRecord::Base # Include default devise modules. Others available are: # :token_authenticatable, :confirmable, :lockable and :timeoutable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable has_many :owned_organizations, :class_name => 'Organization', :foreign_key => :owner_id has_many :organization_memberships has_many :organizations, :through => :organization_memberships # Setup accessible (or protected) attributes for your model attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :username, :owned_organizations_attributes accepts_nested_attributes_for :owned_organizations ...end
My Organization Model:
class Organization < ActiveRecord::Base belongs_to :owner, :class_name => 'User' has_many :organization_memberships has_many :users, :through => :organization_memberships has_many :contracts attr_accessor :plan_name after_create :set_owner_membership, :set_contract ...end
My view : 'devise/registrations/new.html.erb'
<h2>Sign up</h2><% resource.owned_organizations.build if resource.owned_organizations.empty? %><%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %> <%= devise_error_messages! %> <p><%= f.label :name %><br /> <%= f.text_field :name %></p> <p><%= f.label :email %><br /> <%= f.text_field :email %></p> <p><%= f.label :username %><br /> <%= f.text_field :username %></p> <p><%= f.label :password %><br /> <%= f.password_field :password %></p> <p><%= f.label :password_confirmation %><br /> <%= f.password_field :password_confirmation %></p> <%= f.fields_for :owned_organizations do |organization_form| %> <p><%= organization_form.label :name %><br /> <%= organization_form.text_field :name %></p> <p><%= organization_form.label :subdomain %><br /> <%= organization_form.text_field :subdomain %></p> <%= organization_form.hidden_field :plan_name, :value => params[:plan] %> <% end %> <p><%= f.submit "Sign up" %></p><% end %><%= render :partial => "devise/shared/links" %>