Search code examples
ruby-on-railsruby-on-rails-4deviserails-engines

param is missing or the value is empty - Rails 4 Engine


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.

enter image description here

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

Sign up

<%= 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 %>

Solution

  • 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.