Adding custom fields to Devise

Become a Subscriber

Adding custom fields to a Devise User

When using devise we may find ourselves needing to add more fields to a devise user such as preferences and naming conventions. This article is to show you how to add a custom field to your devise user.

Add custom field to the migration

In this use case we are going to add unit preferences for a user. Whether they would like to have Imperial or Metric units on the application. So we will add the unit_prefs field to our migration

class AddFieldsToUsers < ActiveRecord::Migration
  def change
    add_column :users, :unit_prefs, :string
  end
end

Run your database migration to add this column. Make sure to remove the old schema as that could cause your db not to update.

Adding the form field inside the devise views

We will have two different form files to add our new field to…

app/views/devise/registration/new.html
app/views/devise/registration/edit.html

Inside both of these, my preference is to use a select box to select which unit a user would like to see in the application.

f.select(:unit_prefs, [‘metric’, ‘imperial’)

Now when we submit the form and check our database the fields are still nil. What’s going on!?

Configuring permitted parameters for devise controllers

Due to Rails 4 security we have to explicitly state which parameters are permitted inside a controller. Luckily we don’t need to go into the devise controllers themselves but access them from our ApplicationController like so…

class ApplicationController < ActionController::Base
  before_filter :configure_devise_permitted_parameters, if: :devise_controller?

  protected

  def configure_devise_permitted_parameters
    permitted_params = [:email, :password, :password_confirmation, :unit_prefs]

    if params[:action] == 'update'
      devise_parameter_sanitizer.for(:account_update) { 
        |u| u.permit(permitted_params << :current_password)
      }
    elsif params[:action] == 'create'
      devise_parameter_sanitizer.for(:sign_up) { 
        |u| u.permit(permitted_params) 
      }
    end
  end
end

And now when we create or edit a user we will be able to update the database as to our user’s unit preferences. Let us know how this article worked out for you in the comments.