设计用户名不保存在数据库中 ROR
Devise Username not saving in database ROR
首先,我的问题与 this one 等其他 Devise 用户名问题非常相似,但它的独特之处在于我的问题似乎是数据库。我完全希望一旦我的问题得到回答,它就会给我带来 'duh' 时刻,但我需要第二双眼睛。
我的问题是注册过程有效,用户被保存到数据库并自动登录,除了用户名保存。除此以外一切正常。当第一次致力于解决方案时,我认为这是一个强参数问题,但包含用户名....所以这里是代码:
user.rb
class User < ActiveRecord::Base
validates :username, presence: true, uniqueness: { case_sensitive: false}
validate :validate_username
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessor :login
def self.find_first_by_auth_conditions(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:username)
where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
else
where(conditions).first
end
end
def validate_username
if User.where(email: username).exists?
errors.add(:username, :invalid)
end
end
end
application_controller.rb
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protect_from_forgery with: :exception
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:login, :username, :email, :password, :password_confirmation, :remember_me) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :username, :email, :password, :remember_me) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password, :password_confirmation, :current_password) }
end
end
devise.rb
Devise.setup do |config|
require 'devise/orm/active_record'
config.case_insensitive_keys = [:email, :username]
config.authentication_keys = [:login]
config.strip_whitespace_keys = [:email, :username]
config.confirmation_keys = [:login]
config.reset_password_keys = [:login]
end
routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: {
registrations: 'users/registrations', sessions: 'users/sessions'
}
...
end
我还编辑了视图以包含用户名字段
<%= bootstrap_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.text_field :username, autofocus: true %>
</div>
有没有我遗漏的东西可以让所有其他信息正确保存到数据库但阻止用户名保存?
感谢您的所有帮助
编辑:这是 'users' 的架构,表明我确实有用户名。
create_table "users", force: :cascade do |t|
t.string "username", default: "", 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.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
我最近测试的服务器日志:
Started POST "/users" for 127.0.0.1 at 2015-10-04 13:21:07 -0700
Processing by Users::RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"r+jgrIFotF3juYTmMiZhH3K23jzsnTfJOJ6K3kafjfyESs9uX95QKfCSUZQwjS6nyxnOVLpMH4g3S2FNfIGAbA==", "user"=>{"username"=>"test9", "email"=>"test9@test9.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
(6.7ms) BEGIN
User Exists (1.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."username") = LOWER('test9') LIMIT 1
User Exists (5.4ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = LIMIT 1 [["email", "test9"]]
User Exists (0.9ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'test9@test9.com' LIMIT 1
SQL (2.0ms) INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at") VALUES (, , , ) RETURNING "id" [["email", "test9@test9.com"], ["encrypted_password", "deleted"], ["created_at", "2015-10-04 20:21:08.017736"], ["updated_at", "2015-10-04 20:21:08.017736"]]
(8.0ms) COMMIT
(14.0ms) BEGIN
SQL (0.8ms) UPDATE "users" SET "last_sign_in_at" = , "current_sign_in_at" = , "last_sign_in_ip" = , "current_sign_in_ip" = , "sign_in_count" = , "updated_at" = WHERE "users"."id" = [["last_sign_in_at", "2015-10-04 20:21:08.060016"], ["current_sign_in_at", "2015-10-04 20:21:08.060016"], ["last_sign_in_ip", "127.0.0.1/32"], ["current_sign_in_ip", "127.0.0.1/32"], ["sign_in_count", 1], ["updated_at", "2015-10-04 20:21:08.083347"], ["id", 9]]
(8.1ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 508ms (ActiveRecord: 47.1ms)
更多信息:
当运行控制台中User.create方法直接用户名保存正确
[1] pry(main)> User.create(username: "test11", email: "test11@test11.com", password: "password", password_confirmation: "password")
(0.3ms) BEGIN
User Exists (1.0ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."username") = LOWER('test11') LIMIT 1
User Exists (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = LIMIT 1 [["email", "test11"]]
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'test11@test11.com' LIMIT 1
SQL (0.5ms) INSERT INTO "users" ("username", "email", "encrypted_password", "created_at", "updated_at") VALUES (, , , , ) RETURNING "id" [["username", "test11"], ["email", "test11@test11.com"], ["encrypted_password", "deleted"], ["created_at", "2015-10-05 17:22:11.677278"], ["updated_at", "2015-10-05 17:22:11.677278"]]
(3.7ms) COMMIT
=> #<User:0x00000004ac4550
id: 10,
username: "test11",
email: "test11@test11.com",
encrypted_password: "deleted",
和我的用户注册控制器,因为我已经在该控制器和应用程序控制器中尝试了参数:
class Users::RegistrationsController < Devise::RegistrationsController
before_filter :configure_sign_up_params, only: [:create]
before_filter :configure_account_update_params, only: [:update]
# protected
def configure_sign_up_params
binding.pry
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:login, :username, :email, :password, :password_confirmation) }
end
# If you have extra params to permit, append them to the sanitizer.
def configure_account_update_params
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:login, :username, :email, :password, :password_confirmation, :current_password) }
end
end
经过大量的反复试验和其他编码人员的一些建议后,我发现问题出在两个部分。 1 部分是我没有足够频繁地重新启动我的服务器,所以我虽然正在测试的一些更改实际上并没有加载。我的问题的第二部分是,即使我在应用程序控制器中正确设置了强参数,因为我也在我的 registrations_controller.rb 中设置了它们(并且没有完全注释掉),registrations_controller 覆盖了我的其他设置。我没有 :login 作为注册控制器中的参数,并且(即使上面列出了)上面列出的更改由于没有重新启动服务器而没有注册(参见第 1 部分).... /facepalm
首先,我的问题与 this one 等其他 Devise 用户名问题非常相似,但它的独特之处在于我的问题似乎是数据库。我完全希望一旦我的问题得到回答,它就会给我带来 'duh' 时刻,但我需要第二双眼睛。
我的问题是注册过程有效,用户被保存到数据库并自动登录,除了用户名保存。除此以外一切正常。当第一次致力于解决方案时,我认为这是一个强参数问题,但包含用户名....所以这里是代码:
user.rb
class User < ActiveRecord::Base
validates :username, presence: true, uniqueness: { case_sensitive: false}
validate :validate_username
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessor :login
def self.find_first_by_auth_conditions(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:username)
where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
else
where(conditions).first
end
end
def validate_username
if User.where(email: username).exists?
errors.add(:username, :invalid)
end
end
end
application_controller.rb
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protect_from_forgery with: :exception
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:login, :username, :email, :password, :password_confirmation, :remember_me) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :username, :email, :password, :remember_me) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password, :password_confirmation, :current_password) }
end
end
devise.rb
Devise.setup do |config|
require 'devise/orm/active_record'
config.case_insensitive_keys = [:email, :username]
config.authentication_keys = [:login]
config.strip_whitespace_keys = [:email, :username]
config.confirmation_keys = [:login]
config.reset_password_keys = [:login]
end
routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: {
registrations: 'users/registrations', sessions: 'users/sessions'
}
...
end
我还编辑了视图以包含用户名字段
<%= bootstrap_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.text_field :username, autofocus: true %>
</div>
有没有我遗漏的东西可以让所有其他信息正确保存到数据库但阻止用户名保存?
感谢您的所有帮助
编辑:这是 'users' 的架构,表明我确实有用户名。
create_table "users", force: :cascade do |t|
t.string "username", default: "", 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.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
我最近测试的服务器日志:
Started POST "/users" for 127.0.0.1 at 2015-10-04 13:21:07 -0700
Processing by Users::RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"r+jgrIFotF3juYTmMiZhH3K23jzsnTfJOJ6K3kafjfyESs9uX95QKfCSUZQwjS6nyxnOVLpMH4g3S2FNfIGAbA==", "user"=>{"username"=>"test9", "email"=>"test9@test9.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
(6.7ms) BEGIN
User Exists (1.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."username") = LOWER('test9') LIMIT 1
User Exists (5.4ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = LIMIT 1 [["email", "test9"]]
User Exists (0.9ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'test9@test9.com' LIMIT 1
SQL (2.0ms) INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at") VALUES (, , , ) RETURNING "id" [["email", "test9@test9.com"], ["encrypted_password", "deleted"], ["created_at", "2015-10-04 20:21:08.017736"], ["updated_at", "2015-10-04 20:21:08.017736"]]
(8.0ms) COMMIT
(14.0ms) BEGIN
SQL (0.8ms) UPDATE "users" SET "last_sign_in_at" = , "current_sign_in_at" = , "last_sign_in_ip" = , "current_sign_in_ip" = , "sign_in_count" = , "updated_at" = WHERE "users"."id" = [["last_sign_in_at", "2015-10-04 20:21:08.060016"], ["current_sign_in_at", "2015-10-04 20:21:08.060016"], ["last_sign_in_ip", "127.0.0.1/32"], ["current_sign_in_ip", "127.0.0.1/32"], ["sign_in_count", 1], ["updated_at", "2015-10-04 20:21:08.083347"], ["id", 9]]
(8.1ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 508ms (ActiveRecord: 47.1ms)
更多信息:
当运行控制台中User.create方法直接用户名保存正确
[1] pry(main)> User.create(username: "test11", email: "test11@test11.com", password: "password", password_confirmation: "password")
(0.3ms) BEGIN
User Exists (1.0ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."username") = LOWER('test11') LIMIT 1
User Exists (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = LIMIT 1 [["email", "test11"]]
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'test11@test11.com' LIMIT 1
SQL (0.5ms) INSERT INTO "users" ("username", "email", "encrypted_password", "created_at", "updated_at") VALUES (, , , , ) RETURNING "id" [["username", "test11"], ["email", "test11@test11.com"], ["encrypted_password", "deleted"], ["created_at", "2015-10-05 17:22:11.677278"], ["updated_at", "2015-10-05 17:22:11.677278"]]
(3.7ms) COMMIT
=> #<User:0x00000004ac4550
id: 10,
username: "test11",
email: "test11@test11.com",
encrypted_password: "deleted",
和我的用户注册控制器,因为我已经在该控制器和应用程序控制器中尝试了参数:
class Users::RegistrationsController < Devise::RegistrationsController
before_filter :configure_sign_up_params, only: [:create]
before_filter :configure_account_update_params, only: [:update]
# protected
def configure_sign_up_params
binding.pry
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:login, :username, :email, :password, :password_confirmation) }
end
# If you have extra params to permit, append them to the sanitizer.
def configure_account_update_params
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:login, :username, :email, :password, :password_confirmation, :current_password) }
end
end
经过大量的反复试验和其他编码人员的一些建议后,我发现问题出在两个部分。 1 部分是我没有足够频繁地重新启动我的服务器,所以我虽然正在测试的一些更改实际上并没有加载。我的问题的第二部分是,即使我在应用程序控制器中正确设置了强参数,因为我也在我的 registrations_controller.rb 中设置了它们(并且没有完全注释掉),registrations_controller 覆盖了我的其他设置。我没有 :login 作为注册控制器中的参数,并且(即使上面列出了)上面列出的更改由于没有重新启动服务器而没有注册(参见第 1 部分).... /facepalm