Joe
Joe

Reputation: 864

Rails Devise model won't use custom model controller?

In a Rails (version 4.0.2) have a simple model I generated with the Devise gem (version 3.0.4) called User. I want to customize the controller. So I made a file "user_controller":

class UserController < Devise::SessionsController

def create
    super
    puts "this works"

end

end

Here are my routes:

SecretApp::Application.routes.draw do

root  'static_pages#home'
match '/about',   to: 'static_pages#about',   via: 'get'
match '/profile', :to => "profile#show",       via:'get'

devise_for :users, :controllers => {:registrations => "registrations", :sessions => "user"}

end

I'm assuming when overriding a Devise controller, you have to call super in each method unless you are completely overriding the method, correct? In any case, when I create a new User, the console never prints "this works", so I'm pretty sure the controller is not being used. Why?

I did however manage to override my registrations controller for the User model, which confuses me because I'm using the same method to override the User controller (besides the inherited super class and the controller name). I'm sure of this because I have puts "this is ok" in the the new method and it does print that to the console.

Upvotes: 1

Views: 1694

Answers (1)

Ashitaka
Ashitaka

Reputation: 19203

I agree with Zach. A controller that inherits from Devise::SessionsController should definitely not be called UserController. At most, that controller should be inheriting from Devise::RegistrationsController. Also, Rails' conventions dictate that you name your controller in the plural form, UsersController. Regardless, this is why your code is not working:

When you call super, the create action inside Devise::SessionsController is reached. Notice how, in the last line of that action, the respond_with method is called. This method is the one responsible for rendering a template, generating a response. Once this line is reached, your code will not run.

You have thus 2 options:

  1. Call your custom code before you call super:

    def create
      puts "this works"
      super
    end
    
  2. Or take advantage of the fact that Devise's create action has this line:

    yield resource if block_given?
    

    You can then call your custom code like this:

    def create
      super do |resource|
        puts "this works"
      end
    end
    

    This is all mentioned in Devise's readme.

In the second option, Devise is using two awesome Ruby features: blocks, and yielding. You can learn more about blocks and yield with RubyMonk, I highly recommend it!

Upvotes: 1

Related Questions