设计用户名不保存在数据库ROR

时间:2015-10-04 21:20:19

标签: ruby ruby-on-rails-4 devise postgresql-9.4

首先,我的问题与其他Devise用户名问题非常相似,例如this one,但它的独特之处在于我的问题似乎是数据库。我完全相信,一旦我的问题得到解答,它将为我带来'呃'的时刻,但我需要第二双眼睛。

我的问题是注册过程有效,用户保存到数据库并自动登录,但用户名保存除外。一切都有效,除此之外。当我第一次尝试解决方案时,我认为这是一个强参数的问题,但是包含了用户名....所以这里是代码:

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>

我是否遗漏了一些可以让所有其他信息正确保存到数据库但阻止用户名保存的内容?

感谢您提供任何帮助

编辑:这是“用户”的架构,表明我确实拥有用户名。

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" = $1 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 ($1, $2, $3, $4) 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" = $1, "current_sign_in_at" = $2, "last_sign_in_ip" = $3, "current_sign_in_ip" = $4, "sign_in_count" = $5, "updated_at" = $6 WHERE "users"."id" = $7  [["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" = $1 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 ($1, $2, $3, $4, $5) 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",

和我的用户控制器进行注册,因为我在该控制器以及应用程序控制器中都尝试过params:

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 个答案:

答案 0 :(得分:0)

经过多次试验和错误以及来自其他编码员的一些建议后,我发现问题是2部分。 1部分是因为我没有经常重新启动我的服务器,所以我测试的一些更改实际上并没有加载。问题的第二部分是即使我在应用程序控制器中设置了强大的params,因为我也将它们设置在我的registrations_controller.rb中(并没有完全注释掉),registrations_controller覆盖了我的其他设置。我没有:登录作为注册控制器中的参数和(即使它在上面列出)上面列出的更改没有注册,因为没有重新启动服务器(参见第1部分).... / facepalm