The following blog post contains material either currently found or soon to be incorporated into my new book, "Easy Active Record for Rails Developers". Among many other topics, you'll learn about model generation, migrations, validations, associations, scopes, joins, includes, forms integration, nested forms, and model testing with RSpec and FactoryGirl. The book is now available, head over to this website's home page to learn more.


The fantastic Devise gem’s default users table is pretty sparse, containing only two user-related items: an e-mail address and password. Chances are you will want to ask for additional identifying data, such as the user’s name, city, or date-of-birth. Fortunately you can easily add columns and integrate them into the Devise-managed workflow. Let’s work through an example in which we’ll add the user’s name to the users table and account management form.

Begin by creating the necessary migration:

$ rails g migration addNameToUsers name:string
  invoke  active_record
  create    db/migrate/20140909130956_add_name_to_users.rb

Next, incorporate the name column into the users table by running the migration:

$ rake db:migrate
  == 20140909130435 AddNameToUsers: migrating ========
  -- add_column(:users, :name, :string)
     -> 0.0249s
  == 20140909130435 AddNameToUsers: migrated (0.0250s) ========

Next, open the app/views/devise/registrations/edit.html.erb view and add the appropriate field just as you did in Chapter 5:

<div class="form-group">
  <%= f.label :name %>
  <%= f.text_field :name, class: 'form-control' %>
</div>

If you reload /users/edit you’ll see the new field. However, if you enter a name, submit the form, and subsequently return to /users/edit, you’ll see the name has not been persisted. This is because Devise does not for security reasons simply allow updates to any attribute other than those it specifically declares as being safe. There are a number of different solutions to informing Devise of your wish to update another attribute, however in my experience the easiest approach is to add the following code to your project’s /app/controllers/application_controller.rb:

before_filter :configure_devise_parameters, if: :devise_controller?

protected
def configure_devise_parameters
  devise_parameter_sanitizer.for(:account_update) << :name
end

This tells Rails to execute the method configure_devise_parameters if the executing controller is Devise-related. In doing so, it will add the name attribute to the Devise parameter sanitizer when updating an account.

Comments