对设计模型中的新字段进行自定义验证并使用相同的电子邮件地址创建多个用户

rem*_*ses 2 ruby validation ruby-on-rails devise

我是 Rails 新手,我已经开始使用“Devise” gem 在示例 Rails 应用程序中构建身份验证功能。

我添加了一个迁移,以在名为User 的设计模型中添加一个名为username的新列。

我还添加了一些关于我创建的用户名列的验证,因此我的 user.rb 如下所示:

class User < ApplicationRecord

devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable


validates_presence_of :username
validates_uniqueness_of :username  
validates_length_of :username, :minimum => 5, :maximum => 10 
end
Run Code Online (Sandbox Code Playgroud)

现在,每次在新用户注册期间,我都会得到用户名验证,尽管它不应该得到验证。

例如,它告诉我即使用户名已填写,用户名也不应该为空。

用户名至少应包含 5 个字符,尽管如此。

我究竟做错了什么?在控制台中,我可以看到在表单提交期间在参数中传递的用户名以及:Unpermissed argument :username

其次,我想使用相同的电子邮件地址但不同的用户名创建多个注册。

我怎样才能做到这一点?

我正在使用 ruby​​ 2.4.1 和 Rails 5.1.4。谢谢。

max*_*max 5

您必须做至少四件事才能使其发挥作用:

1. 设置正确的验证

由于您没有使用可验证模块,因此您应该确保正确验证用户:

class User < ApplicationRecord

  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable

  validates_presence_of     :email # optional
  validates_presence_of     :username # required
  validates_uniqueness_of   :username # required    
  validates_presence_of     :password, if: :password_required? # recommended
  validates_confirmation_of :password, if: :password_required? # recommended
  validates_length_of       :password, within: password_length, allow_blank: true # recommended
end
Run Code Online (Sandbox Code Playgroud)

2. 配置设备使用 :username 而不是 :email 作为身份验证列:

# config/initializers/devise.rb
# ...
config.authentication_keys = [ :username ]
config.reset_password_keys = [ :username  ]
config.confirmation_keys =   [ :username  ]
Run Code Online (Sandbox Code Playgroud)

您可能需要搜索config/initializers/devise.rb:email查找其他选项。

3. 删除电子邮件的数据库唯一性约束:

生成一个新的迁移并将其放入change块中:

remove_index "users", name: "index_users_on_email"
add_index "users", "email", unique: false 
Run Code Online (Sandbox Code Playgroud)

如果您尚未确保您在users.username.

4. 将参数列入白名单。

由于可配置性的原因,Devise 中的参数白名单比普通 Rails 资源要复杂一些。

您需要将sign_up和sign_in的用户名参数列入白名单:

class ApplicationController < ActionController::Base
  # ...
  before_action :configure_devise_parameters, if: :devise_controller?

  # ...

  private
  def configure_devise_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
    devise_parameter_sanitizer.permit(:sign_in, keys: [:username], except: [:email])
  end
end
Run Code Online (Sandbox Code Playgroud)

最好的参考是阅读评论很好的来源。