Customize Devise Timeoutable Length of Time Until Auto Sign Out

The Devise gem is awesome and super useful if you have users logging into your app.  It has a built-in feature for making user sessions automatically signed out or logged out after a certain period of time. Devise calls this :timeoutable.  You can easily customize how long until a user is signed out by going to the config/initializers/devise.rb file and editing the config.timeout_in = 30.minutes line.

  # ==> Configuration for :timeoutable
  # The time you want to timeout the user session without activity. After this
  # time the user will be asked for credentials again. Default is 30 minutes.
  config.timeout_in = 30.minutes # EDIT THIS LINE

So in mine I changed it to

config.timeout_in = 5.minutes

while testing.

Let me know if this was helpful!

Override Devise Controller with Custom Fields and Strong Parameters

So I already wrote a post on how to override the Devise Controller.  In this case I’ve added a field to the User model during the development process, however I need to add that field to the white list for strong parameters so that it can be edited and updated from the views.  This is normally done in the controller, however it can be a bit trickier when we are overriding or customizing the Devise controller.

After searching around and reading several different ideas, this is what worked for me.

Add a function in the normal application_controller.rb, where we specifically permit our new User model fields.

Screen Shot 2014-09-05 at 7.15.03 AM

 

So here we create a function configure_permitted_parameters that adds my custom fields, in this case :name and :certificate to the white list for new users singing up and for updated or editing their accounts.

We then create a before_filter to only call this function in the devise controller.  Pretty simple right?

The device documentation mentions this function here. Another resources is this StackOverflow question.

Credit also to this gist, although it didnt work directly for me until I put the code in the application controller.

Customize Devise Flash Message Content in Rails

Devise automatically includes great flash messages, however sometimes you want to edit or make your own.  In my case I have customized the devise controller for registrations, and I want to call a flash message in my custom devise registrations controller. (refer to my post on how to override and create a custom devise controller here).

So by looking in the devise source code, in particular the registrations_controller.rb, we see how to do this. First, in the devise.en.yml file, create your custom flash message content in the right location. In my case I want it to be in the registrations controller, so in the devise.en.yml under registrations I created a new flash message like this:

registrations:
  wrong_beta_password: "You need the beta password to create an account." # this one is my custom one
  # Devise default flash messages here

Now, simply call this message in your custom devise controller:

set_flash_message :notice, :wrong_beta_password if is_flashing_format?

That’s it!

How to Override and Customize the Devise Controller in Rails

Judging by the number of different StackOverflow questions, there are a lot of people trying to do this, and a lot of confusion. Here is how I did it, and hopefully it helps you.

I have a User and a Verifier model.  What I want to do is create a new Verifier every time I create a new user, and pass in the user.id for the User into the verifier.user_id so that they are mapped together.

In order to do this I want to not really override but add additional functionality to the existing devise controller that handles when new users are created (and destroyed).  So I need to access the RegistrationsController#Create function in devise.

First thing is to create a new folder in the ‘app/controllers‘ folder where we can put my custom controller.  I called mine ‘app/controllers/my_devise‘.  Then create a new file in this folder called registrations_controller.rb

Screen Shot 2013-12-27 at 1.24.38 PM

It is called ‘registrations_controller‘ because that is what devise calls its controller that handles new user sign ups.  We want it to inherit from the original devise controller:

Screen Shot 2013-12-27 at 1.27.23 PM

Ok, so since I want to create some custom logic that happens when a new user is created, I want to override and customize the ‘create’ function:

Screen Shot 2013-12-27 at 1.36.31 PM

So you’ll notice the ‘super’ command is called at the beginning.  This is because I want to keep the original functionality of the devise create function, and just add my own additional logic.  If you want to completely customize and override the devise create function, then you don’t want this line.

Now at fist I was tempted to use ‘if user.save’, because I want to create a new Verifier when a User is created, however the devise registrations controller uses ‘resource’, so thats what I want to access here.  In my case, the model that I use with devise is User, so in my case ‘resource’ means ‘user’.  Yours will depend on how you set up devise at the beginning.

Now importantly don’t forget to also delete the linked Verifier when the User is deleted.  I used the same idea to override and customize the destroy function:

Screen Shot 2013-12-27 at 1.39.28 PM

Some things to note here.  I  used the find_all_by_user_id function to get all the Verifiers that are linked to the User that we are destroying in this function.  Since each User only has one Verifier,  I could have used find_by_user_id.  I decided to use find_all_by_user_id, just in case something weird happened and two Verifiers were linked to one User.  This would ensure they all get deleted.  Now note that find_all_by_user_id returns an array of values, even if the array only has a single element.  So thats why I need to use the each function to iterate through the array, even if it only has a single element.  This is because the destroy function cannot be called on an array, but only on a single instance.

So now when I create a new User, a Verifier is also created whose user_id value matches the User.id value.

Two things remain to do.  First, we need to copy the ‘views/devise/registrations‘ files into a custom folder that matches the custom folder we made for our registrations_controller.rb.  So I copied mine into ‘views/my_devise/registrations

Screen Shot 2013-12-27 at 1.54.47 PM

Lastly we need to update the config/routes.rb file to point to our custom controller

Screen Shot 2013-12-27 at 1.56.45 PM

If you get a routing error, try using { :registrations => "my_devise/registrations" } I got an error in production when running on heroku, and using this route worked.

That’s it!

Now I’ve been thinking that there might be a better way to do this linking a Verifier with a User with rails associations, so if you know of one, please let me know!

Here is a link to the devise registrations_controller.rb so you can see the default functions.  The devise documentation is also helpful, and I want to give credit to these StackOverflow questions which also helped me a lot. (one, two, three)

Want to learn more about Ruby on Rails?  Checkout OneMonthRails, what I used to get started in Rails. Best Rails course I’ve ever seen!