Ruby on Rails: Custom Devise Registration Controller, Asking For Create Action

17,756

Your controller of registration inherits from the wrong class: DeviseController It is a base class for a registration and has no "create" method, and so does your custom Devise::RegistrationsController class (it has only edit and update methods) - it incurs the error.

In order to create your own custom registration controller for users with fallback to the original devise methods, I suggest you do the following:
1. create "users" folder in controllers folder
2. create there registrations_controller.rb file, and define class there:

Users::RegistrationsController < Devise::RegistrationsController

and override any actions ("edit" and "update")
3. inform the "routes.rb" file about changes:

  devise_for :users, :controllers => { registrations: 'users/registrations' }
Share:
17,756
hellomello
Author by

hellomello

On the path to learning all things React Native at the moment. I'll be right back!

Updated on July 24, 2022

Comments

  • hellomello
    hellomello almost 2 years

    I have a custom registration controller, but I don't want to override a create action from devise. When I try to sign up a user, I get this error:

    Unknown action
    
    The action 'create' could not be found for Devise::RegistrationsController
    

    Is it asking for it because I have a custom registration controller? If so, does that mean I need to copy all the actions that I'm not overriding from here: https://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb

    Or its because there's something wrong with my application?

    My routes:

      devise_for :user, :controllers => { :registrations => "devise/registrations" }, :skip => [:sessions] do 
        get 'signup' => 'devise/registrations#new', :as => :new_user_registration 
        post 'signup' => 'devise/registrations#create', :as => :user_registration 
      end
    

    This is my devise registration controller

    class Devise::RegistrationsController < DeviseController
    
      skip_before_filter :require_no_authentication
    
      def edit
        @user = User.find(current_user.id)
        @profile = Profile.new
      end 
    
      def update
        # required for settings form to submit when password is left blank
        if params[:user][:password].blank? && params[:user][:password_confirmation].blank?
            params[:user].delete(:password)
            params[:user].delete(:password_confirmation)
        end
    
        @user = User.find(current_user.id)
        if @user.update_attributes(params[:user])
          set_flash_message :notice, :updated
          # Sign in the user bypassing validation in case his password changed
          sign_in @user, :bypass => true
          redirect_to after_update_path_for(@user)
        else
          render "edit"
        end
    
      end
    
    
      protected
        def after_update_path_for(resource)
          user_path(resource)
        end
    
        def after_sign_up_path_for(resource)
          user_path(resource)
        end
    
    end
    

    This is the registration form:

    <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
     ... 
      <div>
        <%= button_tag :type => :submit, :class => "btn btn-large btn-inverse" do %>
        Sign up
        <% end %>
      </div>
    ...
    <% end %>
    
  • hellomello
    hellomello over 10 years
    That works. Why is it that it can't be devise as a folder name?
  • Roaring Stones
    Roaring Stones over 10 years
    actually, I think it can be ) but I usually follow rails naming conventions for I got a painful experience of debugging such applications: errors are tend to be in very unexpected places and often the only reason, that some naming convention was not followed.
  • Ricbermo
    Ricbermo over 10 years
    @RoaringStones you are missing the 's' and the end of registration. The name must be registrations_controller.rb
  • Constant Meiring
    Constant Meiring over 10 years
    For anybody wondering - unlike other update routes, you won't have an :id param in the route. This is because the class is not meant to update other users, just the current user. Thus, when creating links in views for updating the user, you need to leave out the id in edit_user_registrations_path - ie. NOT edit_user_registrations_path(current_user.id)