感谢您回答我之前的问题,但我遇到了一个新问题。
我正在创建一个自定义验证器,用于验证用户是否输入了干净的单词。这个 在我的 UsersController 上用作验证方法。
我正在使用 Obscenity gem,但创建了一些我自己的方法来确保质量数据。
错误信息
NoMethodError: Undefined method include? for Nil:NilClass
问题在于,如果记录已经存在,我的方法会起作用,但在记录创建期间它们不起作用。我试图通过使用来解决这个问题
:on => [:create, :update]
但我仍然收到同样的错误。
验证方法
class MyValidator < ActiveModel::Validator
def mystery_setup
@mystery_words = # This is a mystery, I can't tell you.
@mystery_c = @mystery_words.map(&:capitalize)
@mystery_u = @mystery_words.map(&:upcase)
@mysteries = @mystery_words + @mystery_c + @mystery_u
@new_mysteries = @mysteries.map{|mystery|mystery.tr("A-Za-z", "N-ZA-Mn-za-m")}
end
def validate (user)
mystery_setup
if Obscenity.profane?(user.name) \
|| @new_mysteries.any?{|mystery|user.name.include?(mystery)} \
|| @new_mysteries.any?{|mystery|user.email.include?(mystery)} \
|| @new_mysteries.any?{|mystery|user.password.include?(mystery)}
user.errors[:name] << 'Error: Please select a different username'
end
end
end
User.rb(模型)
class User < ActiveRecord::Base
include ActiveModel::Validations
validates_with MyValidator
has_many :favorites, foreign_key: "user_id", dependent: :destroy
has_many :pictures, through: :favorites
has_secure_password
before_create :create_remember_token
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates_presence_of :name, :password, :email
validates_uniqueness_of :name, :email
validates :name, length: { in: 3..20 }
validates :password, length: { minimum: 6 }
validates :email, format: { with: VALID_EMAIL_REGEX }, length: { in: 8..50 }
validates_confirmation_of :password, if: lambda { |m| m.password.present? }
def User.new_remember_token
SecureRandom.urlsafe_base64
end
def User.digest(token)
Digest::SHA1.hexdigest(token.to_s)
end
private
def create_remember_token
self.remember_token = User.digest(User.new_remember_token)
end
end
我也尝试过使用 unless 语句
def validate (user)
mystery_setup
unless User.all.include?(user)
if (Obscenity.profane?(user.name)
|| @new_mysteries.any {|mystery|user.name.include?(mystery)}) \
|| @new_mysteries.any?{|mystery|user.email.include?(mystery)} \
|| @new_mysteries.any?{|mystery|user.password.include?(mystery)}
user.errors[:name] << 'Error: Please select a different username'
end
end
end
end
我尝试使用 unless 语句测试是否有用户,但这也不起作用。
根据此处类似问题的建议,我更改了迁移文件以应对这一领域。
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name, default: 'new'
t.string :password, default: 'new'
t.string :email, default: 'new'
t.timestamps
end
end
end
问题链接
undefined method `include?' for nil:NilClass with partial validation of wizard gem
代码引用
http://guides.rubyonrails.org/active_record_validations.html#performing-custom-validations
通过更改默认值来更改迁移文件并没有解决这个问题,所以我决定在这里提出一个新问题。
此方法适用于更新记录但不适用于创建新记录。
感谢您的帮助。先谢谢你。
编辑
刚刚收到一个很好的建议,以括号格式传递属性。我的代码现在看起来像这样
def validate (user)
mystery_setup
unless User.all.include?(user)
if (Obscenity.profane?(user[:name]) ||
@new_mysteries.any?{|mystery|user[:name].include?(mystery)}) \
||@new_mysteries.any?{|mystery|user[:email].include?(mystery)}
||@new_mysteries.any?{|mystery|user[:password].include?(mystery)}
user.errors[:name] << 'Error: Please select a different username'
end
end
end
目前,只有电子邮件和密码属性有错误。如果我删除最后两个||@new_mysteries.any?行,我的方法适用于过滤名称。
虽然我想保持这种专业性,所以我想让它与其他两种方法一起使用。可能与我使用括号或 || 有关符号?
坚实的进步伙计们,继续保持。
编辑
此外,如果我想在其他类上调用这些验证方法,将其放在辅助文件中会更好吗?
新更新
这是我的用户 Controller 代码
class UsersController < ApplicationController
before_action :signed_in_user, only: [:edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
def index
@users = User.all
end
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
flash[:success] = "Congratulations #{@user.name}! You have successfully created an account"
redirect_to games_path
else
render 'new'
end
end
def edit
end
def update
@user = User.find(params[:id])
end
def favorites
@user = User.find(current_user)
end
def destroy
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url notice: "Please sign in."
end
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
end
最佳答案
你可以这样写:
def validate (user)
mystery_setup
user.errors[:name] << 'Tsk! Tsk! Please select a different username' if
Obscenity.profane?(user[:name]) ||
[:name, :email, :password].product(@new_mysteries).any? { |sym, mystery|
(str = user.public_send sym) && str.include?(mystery) }
end
感谢@Arup 的修复。
如果您希望减少实例变量的数量,您可以将第一行更改为:
new_mysteries = mystery_setup
并将@new_mysteries
更改为new_mysteries
。
关于ruby-on-rails - 未定义的方法包括?对于零 :NilClass,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25143919/