在使用'undefined method downcase'验证方法破坏规范之前

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在使用'undefined method downcase'验证方法破坏规范之前相关的知识,希望对你有一定的参考价值。

在我的User模型中,我有一个名为normalize_params的before_validation方法,该方法使用downcase。

class User < ApplicationRecord
  before_validation :normalize_params, on: [:create, :update]

  validates :email, :presence => true
  validates :email, :uniqueness => true

  validates :username, :presence => true
  validates :username, :uniqueness => true

  validates_confirmation_of :password

  scope :all_users_except, -> (current_user) {
    where.not(id: current_user)
  }

  has_attached_file :avatar, styles: { medium: "300x300>", thumb: 
  "100x100>" }, default_url: "/images/missing.png"
  validates_attachment_content_type :avatar, content_type: 
  /Aimage/.*z/
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

  private

  def normalize_params
    self.name = name.downcase.titleize
    self.email = email.downcase
    self.home = home.downcase.titleize
  end
end

所有这一切都在我的应用程序中完美运行,但是当我们的测试因为这个错

NoMethodError:
  undefined method `downcase' for nil:NilClass

这是我的测试......

require 'rails_helper'

describe User, 'validation' do
  it { should validate_presence_of :email }
  it { should validate_presence_of :username }
  it { should validate_presence_of :password }
end

如果我将before_validation和normalize_params取出,那么我的测试就会通过。

答案

根据documentation的例子,你可以在之前使用attribute_present?

class User < ApplicationRecord
  before_validation :normalize_params, on: %i[create update]

  validates :email,    presence: true, uniqueness: true
  validates :username, presence: true, uniqueness: true

  private

  def normalize_params
    titleize_name
    downcase_email
    # You can any other here.
  end

  def titleize_name
    self.name = name.downcase.titleize if attribute_present? 'name'
  end

  def downcase_email
    self.email = email.downcase if attribute_present? 'email'
  end
end

请注意,您可以:

  • 使用%i[]创建符号数组。
  • 通过逗号分隔它们来验证存在性和唯一性。
  • 更喜欢is_expected.to而不是should语法(it { is_expected.to validate_presence_of :attribute }
  • 将每个属性修改分开以便轻松工作并包含它们。
  • 不需要时避免使用哈希火箭。见ruby-style-guide#hash-literals
另一答案

nameemailhome中的任何一个都可能是nil。我建议使用safe navigation operator

def normalize_params
  self.name = name&.downcase&.titleize
  self.email = email&.downcase
  self.home = home&.downcase&.titleize
end

以上是关于在使用'undefined method downcase'验证方法破坏规范之前的主要内容,如果未能解决你的问题,请参考以下文章

ruby on rails错误undefined method `title&#39; for nil:NilClass

jquery模拟点击dhtmlxgrid列表checkbox,显示Cannot call method 'changeState' of undefined

matlab分三段运行时报错Undefined function or method 'Hermite' for input arguments of type '

Cannot read property '_withTask' of undefined

"undefined method `root' for nil:NilClass" error when using "pod install" 解决

reportComplaints.js: Uncaught TypeError: Cannot read property 'message' of undefined