9

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
  • 8,219
  • 39
  • 151
  • 297

1 Answers1

18

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' }
Roaring Stones
  • 1,054
  • 7
  • 22
  • That works. Why is it that it can't be devise as a folder name? – hellomello Aug 23 '13 at 04:52
  • 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. – Roaring Stones Aug 23 '13 at 05:05
  • 2
    @RoaringStones you are missing the 's' and the end of registration. The name must be registrations_controller.rb – Ricbermo Nov 12 '13 at 21:02
  • 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) – Constant Meiring Dec 31 '13 at 12:30