I am building my first ever modular application, my first module is Account and my goal is to have this module handle all the various user models authorizations via Devise.
my first user type is "User", this will be where all general employees login in to the application" (I have decided to go modular with this as i have a few apps coming up what will require similar demands and something modular i can just plug in seems enticing.
My Problem:
I have created the user model, however have added a custom registrations controller, as shown below.
user_registrations_controller.rb
module Account
class UserRegistrationsController < Devise::RegistrationsController
private
def sign_up_params
params.require(:account_users).permit(:email, :password, :password_confirmation)
end
def account_update_params
params.require(:account_users).permit(:email, :password, :password_confirmations, :current_password)
end
end
end
User Model is as follows
module Account
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :lockable
end
end
the out put I am getting on the rails server when I try to register a user is:
Started POST "/account/users" for ::1 at 2016-04-25 00:49:12 -0600
Processing by Account::UserRegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"73uo7aB0DmS/rsZRuopEFvQ3MoTv1YJjdIRishvqEdY7Y2vcrIzwp6gfmUM3fApcDz2Fer5kFA/SjhNibZOGyw==", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
Completed 400 Bad Request in 1ms (ActiveRecord: 0.0ms)
Finally here is a screen grab from the better errors gem.
and an overview of my rake routes output
Prefix Verb URI Pattern Controller#Action
account /account Account::Engine
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) account/user_registrations#cancel
user_registration POST /users(.:format) account/user_registrations#create
new_user_registration GET /users/sign_up(.:format) account/user_registrations#new
edit_user_registration GET /users/edit(.:format) account/user_registrations#edit
PATCH /users(.:format) account/user_registrations#update
PUT /users(.:format) account/user_registrations#update
DELETE /users(.:format) account/user_registrations#destroy
user_confirmation POST /users/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new
GET /users/confirmation(.:format) devise/confirmations#show
user_unlock POST /users/unlock(.:format) devise/unlocks#create
new_user_unlock GET /users/unlock/new(.:format) devise/unlocks#new
GET /users/unlock(.:format) devise/unlocks#show
Routes for Account::Engine:
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) account/user_registrations#cancel
user_registration POST /users(.:format) account/user_registrations#create
new_user_registration GET /users/sign_up(.:format) account/user_registrations#new
edit_user_registration GET /users/edit(.:format) account/user_registrations#edit
PATCH /users(.:format) account/user_registrations#update
PUT /users(.:format) account/user_registrations#update
DELETE /users(.:format) account/user_registrations#destroy
user_confirmation POST /users/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new
GET /users/confirmation(.:format) devise/confirmations#show
user_unlock POST /users/unlock(.:format) devise/unlocks#create
new_user_unlock GET /users/unlock/new(.:format) devise/unlocks#new
GET /users/unlock(.:format) devise/unlocks#show
Im quite flustered here.. there is not alot of documentation on this type of thing. Thanks in advance for your assistance here!
EDIT # 1 -- Add Routes .rb (same between engine and app)
mount Account::Engine => "/account", as: 'account'
devise_for :users,{
class_name: "Account::User",
module: :devise,
controllers: { registrations: 'account/user_registrations' }
}
Adds Registrations New Form
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "users/shared/links" %>
Edit Registration View/Form
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div class="field">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>
Look at the params being sent to your controller:
{"utf8"=>"✓", "authenticity_token"=>"73uo7aB0DmS/rsZRuopEFvQ3MoTv1YJjdIRishvqEdY7Y2vcrIzwp6gfmUM3fApcDz2Fer5kFA/SjhNibZOGyw==", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
The form is sending params as user
because that's what resource
and resource_name
are defined as in the devise view.
So the relevant hash key is :user
instead of :account_users
. The following change should fix the issue:
params.require(:user).permit(...)
alternatively, you can override the param names within the form_for
:
form_for resource, as: 'account_user' do |f|
....
If you go that route, you'll probably want to use account_user
instead of account_users
since you're creating/updating a singular resource, not a collection.