如何在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" %>

解决方法

您的验证需要在类中,而不是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列,也无需向其添加验证。