如何在 Rails 的 Ruby 上设置用户名验证?

How can I set username validation on Ruby on Rails?

我是 Rails 的新手,我建立了一个图书共享平台,我想根据电子邮件名称设置用户名。验证是用户名必须最少 5 个字符,最多 50 个字符。我设置了它,但验证不起作用。错误出现在屏幕上,但用户仍然可以注册。我使用 Devise for User 模型和 Devise wiki。

user.rb

class User < ApplicationRecord
  before_create :set_username

  validates :email, presence: true

  has_many :books

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  attr_accessor :login

  def login
    @login || self.username || self.email
  end

  private
  def set_username
    self.username = self.email.split('@').first 

    validates_length_of :username, 
    :minimum => 5, :maximum => 50, 
    presence: true,
    uniqueness: true
  end

  def self.find_for_database_authentication(warden_conditions)
    conditions = warden_conditions.dup
    if login = conditions.delete(:login)
      where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
    else
      where(conditions).first
    end
  end

  def self.find_first_by_auth_conditions(warden_conditions)
    conditions = warden_conditions.dup
    if login = conditions.delete(:login)
      where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
    else
      if conditions[:username].nil?
        where(conditions).first
      else
        where(username: conditions[:username]).first
      end
    end
  end
end

routes.rb

Rails.application.routes.draw do
  devise_for :users, :path_prefix => 'd'
  resources :dashboard
  resources :books do
    resources :comments
  end
  resources :users
  match '/users/:id', to: 'users#show', via: 'get'
  root 'welcome#index'
  get 'dashboard/index'
  get 'users/index'
end

devise/registiration/new.html.erb

<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= render "devise/shared/error_messages", resource: resource %>

  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
  </div>

  <div class="field">
    <%= f.label :password %>
    <% if @minimum_password_length %>
    <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: "new-password" %>
  </div>

  <div class="field">
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
  </div>

  <div class="actions">
    <%= f.submit "Sign up" %>
  </div>
<% end %>

<%= render "devise/shared/links" %>

您的验证需要在 class 中,而不是在 set_username 方法中,类似于您对存在性验证所做的。

class User < ApplicationRecord
    validates_length_of :username, 
    :minimum => 5, :maximum => 50, 
    presence: true,
    uniqueness: true
end

您可以将电子邮件地址的第一部分用作用户名,方法是将以下内容添加到 user.rb:

  def username
    email.split(/@/).first
  end

这样对于电子邮件为 alex@example.com 的用户,当您致电 user.usernamecurrent_user.username 时,您将收到 alex

您不需要向数据库添加 username 列,也不需要向其添加验证。