I was creating my first Rails app the other day and although the online tutorials are very useful, I couldn’t find a way to have my devise registration form create a new company and assign it to the new User. After a lot of googling and hair pulling I made it work. I created a rails’ app and put it in Github. The last commit highlighting what I did to make it work. You can see it here Example
It turns out it was very simple so here it is
I will leave setting up rails and generating the Devise views for you to google.
You need to already have a User and Company Model
I will assume you have done all that or you can just clone my example from Github Example
First on our config/routes.rb we add this
# We are customizing the registration route to add our company fields devise_for :users, :controllers => { registrations: 'registrations'}
now on our app/controllers/registrations_controller.rb (you will need to create this file)
class RegistrationsController < Devise::RegistrationsController # Because of Rails strong parameter we need to use the Registration controller Override # to sanitize inputs # Devise automatically knows wich one to use private def sign_up_params params.require(:user).permit( :email, :password,:password_confirmation, company_attributes:[:company_name]) end def account_update_params # For updates we make sure to let the Company ID pass through or the form will # generate a new company every time we edit our details params.require(:user).permit(:email,:password, :password_confirmation, :current_password, company_attributes: [:id,:company_name]) end end
Our User model
class User < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable # we set up our User relation ship belongs_to :company # we tell User that we can take company attributes accepts_nested_attributes_for :company validates :email, presence: true, uniqueness: {scope: :company_id} end
Our Company Model
class Company < ActiveRecord::Base # Set up Company to have many_users has_many :users # We want to validate at least one field you can choose any # field you want validates :company_name, presence: true # Add other validations etc... end
Now for Our Views
the new registration app/views/devise/registrations/new.html.erb
Sign up
<% resource.build_company %> <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> <%= devise_error_messages! %><%= f.label :email %>
<%= f.email_field :email, autofocus: true %><%= f.fields_for :company do |builder| %> <%= builder.label :company_name %>
<%= builder.text_field :company_name %> <%end%><%= f.label :password %> <% if @validatable %> (<%= @minimum_password_length %> characters minimum) <% end %>
<%= f.password_field :password, autocomplete: "off" %><%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, autocomplete: "off" %><%= f.submit "Sign up" %><% end %> <%= render "devise/shared/links" %>
now our registration edit form
Edit <%= resource_name.to_s.humanize %>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> <%= devise_error_messages! %><%= f.label :email %>
<%= f.email_field :email, autofocus: true %><%= f.fields_for :company do |builder| %> <%= builder.label :company_name %><% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<%= builder.text_field :company_name %> <%end%>Currently waiting confirmation for: <%= resource.unconfirmed_email %><% end %><%= f.label :password %> (leave blank if you don't want to change it)
<%= f.password_field :password, autocomplete: "off" %><%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, autocomplete: "off" %><%= f.label :current_password %> (we need your current password to confirm your changes)
<%= f.password_field :current_password, autocomplete: "off" %><%= f.submit "Update" %><% end %>Cancel my account
Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %>
<%= link_to "Back", :back %>
Finally for testing purposes i am doing this on my welcome page
-
<% if user_signed_in? %>
- <%= link_to "My Account", edit_user_registration_path %>
- <%= link_to "Log Out", destroy_user_session_path, :method => :delete%> <% else %>
- <%= link_to "Login", new_user_session_path %>
- <%= link_to "Sign Up", new_user_registration_path %> <% end %>
Leave a Reply