imjp
imjp

Reputation: 6695

Devise: Adding first_name to Users

Rails 3.1
Devise 1.4.2

I've added first_name and last_name columns to devise's User table. Then I've used to console to add a first_name and last_name for my first user.

Now, my application.html.erb displays my first name and last name thanks to the following code after I've made sure the user is logged in:

<%= current_user.first_name %> <%= current_user.last_name %>(<%= current_user.email %>)

Here's my problem: when I try to register a new user via the new user form I've created, the first_name and last_name are not stored in the database or something... because when I log in with the new user the code I have on my application.html.erb does not display the first and last name.

Here's the text fields for the first and last name in the new.html.erb:

<p><%= f.label :first_name %><br />
   <%= f.text_field :first_name %></p>

<p><%= f.label :last_name %><br />
   <%= f.text_field :last_name %></p>

<p><%= f.label :email %><br />
   <%= f.email_field :email %></p>

I'd also like to know how to add validation for these new columns I've created (first_name and last_name).

Thanks in advance!

Upvotes: 3

Views: 4628

Answers (4)

Mashpy Rahman
Mashpy Rahman

Reputation: 696

Rails 4+

I have solved the problem. It will also work for rails 4+.

Step 1: Run New Migration

$ rails generate migration AddFieldToUsers first_name:string last_name:string

Optionally, you may wish to change the columns to null: false and within the user model validates presence: true.

 class AddFieldToUsers < ActiveRecord::Migration[6.1]
  def change
    add_column :users, :first_name, :string, null: false
    add_column :users, :last_name, :string, null: false
  end
 end

$ rake db:migrate

Step 2: Add these code on the devise views. If you haven't generated them already, you will need: rails generate devise:views users

  # app/views/devise/registrations/edit.html.erb
  # app/views/devise/registraitons/new.html.erb

  <div class="field">
    <%= f.label :first_name %><br />
    <%= f.text_field :first_name, autofocus: true %>
  </div>

  <div class="field">
    <%= f.label :last_name %><br />
    <%= f.text_field :last_name %>
  </div>

Step 3: add this to your application controller

  # app/controllers/application_controller.rb

  before_filter :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    added_attrs = %i[first_name last_name email password password_confirmation remember_me]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
  end

Upvotes: 1

Thilo
Thilo

Reputation: 17735

Rails 3

By default, devise makes all attributes protected. For any attribute you want to be able to mass assign (e.g via a form), you need to explicitly allow it in your model:

attr_accessible :first_name, :last_name

It worked in your console because you probably did something like this:

@user = User.first
@user.first_name = "foo"
@user.save

But this won't work if the attribute is not accessible:

@user = User.new(:first_name => "foo")
@user.save

You'll should see a warning "Can't mass assign protected attributes" in your log file.

For validations, check out the Rails docs or this guide. For example, to ensure a full name is provided, add

validates_presence_of :first_name, :last_name

to your model.

Upvotes: 9

Santosh Sindham
Santosh Sindham

Reputation: 919

Add the below to your application controller

protected

    def configure_permitted_parameters
        devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:first_name, :last_name, :profile_name, :email, :password, :password_confirmation) }
        devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:first_name, :last_name, :profile_name, :email, :password, :password_confirmation) }


    end

Upvotes: 0

bassneck
bassneck

Reputation: 4043

I think, you forgot to set attr_accessible for your new attributes.

Upvotes: 0

Related Questions