Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails & Devise: devise specific columns not showing up in rails console

I am trying to use Devise on my User model but when I go into rails console and try User.new I only get:

irb(main):002:0> User.new
=> #<User id: nil, first_name: nil, last_name: nil, email: nil, created_at: nil, updated_at: nil>

Why are the devise columns not showing up?

CreateUsers migration:

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :first_name
      t.string :last_name
      t.string :email


      t.timestamps null: false
    end
  end
end

AddDeviseToUsers migration:

class AddDeviseToUsers < ActiveRecord::Migration
  def self.up
    change_table :users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer  :sign_in_count, default: 0, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at


      # Uncomment below if timestamps were not included in your original model.
      # t.timestamps null: false
    end

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    # add_index :users, :confirmation_token,   unique: true
    # add_index :users, :unlock_token,         unique: true
  end

  def self.down
    # By default, we don't want to make any assumption about how to roll back a migration when your
    # model already existed. Please edit below which fields you would like to remove in this migration.
    raise ActiveRecord::IrreversibleMigration
  end
end

Schema shows the columns are there:

  create_table "users", force: :cascade do |t|
    t.string   "first_name"
    t.string   "last_name"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

Any ideas?

like image 765
Jackson Cunningham Avatar asked Jan 20 '17 00:01

Jackson Cunningham


1 Answers

It's a security feature that Devise has in order to restrict its attributes and the critical information it contains to be exposed to API calls.

You can however override this, you need to override serializable_hash method.

# app/models/user.rb

class User < ActiveRecord::Base

   devise :database_authenticatable, :recoverable, :confirmable, :rememberable, :validatable

   ...

   protected

   def serializable_hash(options = nil) 
    super(options).merge(encrypted_password: encrypted_password, reset_password_token: reset_password_token) # you can keep adding attributes here that you wish to expose
  end

end

You can check http://www.rubydoc.info/github/plataformatec/devise/Devise/Models/Authenticatable where a constant is declared to blacklist attributes

BLACKLIST_FOR_SERIALIZATION =[:encrypted_password, :reset_password_token, :reset_password_sent_at, :remember_created_at, :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip, :last_sign_in_ip, :password_salt, :confirmation_token, :confirmed_at, :confirmation_sent_at, :remember_token, :unconfirmed_email, :failed_attempts, :unlock_token, :locked_at]

Hope this answers your question!

like image 112
Aniket Rao Avatar answered Sep 23 '22 07:09

Aniket Rao