问题
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?
回答1:
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!
回答2:
Devise overrides the inspect method to not expose internal attibutes. You can try:
User.new.attributes
or
User.new.encrypted_password
(or whatever attribute you want)
You can check inspect method here
回答3:
If all you want to do it list all the attributes in the Rails console, it is easier to use User.first.serializable_hash(force_except: true)
See http://www.rubydoc.info/github/plataformatec/devise/Devise%2FModels%2FAuthenticatable:serializable_hash
来源:https://stackoverflow.com/questions/41754087/rails-devise-devise-specific-columns-not-showing-up-in-rails-console