ruby-on-rails - 未定义的方法包括?对于零 :NilClass

标签 ruby-on-rails ruby nomethoderror

感谢您回答我之前的问题,但我遇到了一个新问题。

我正在创建一个自定义验证器,用于验证用户是否输入了干净的单词。这个 在我的 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/

相关文章:

ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055)

associations - 工厂女孩与 child 类的联系,显示 nomethoderror : undefined method

ruby-on-rails - Heroku NoMethoderror, remember_token=

ruby-on-rails - 在 Rails 中使用复选框

ruby-on-rails - Phoenix 有什么办法只生成 Controller ,没有模型吗?

ruby-on-rails - RSpec load_missing_constant,期望 X 定义 Y(确实如此)

ruby-on-rails - 在rake任务中调用具有多个任务的多个rake任务

ruby-on-rails - 如何将服务器环境移动到另一台服务器?

ruby - 在 Ruby 中将字符转换为代码

ruby - 使用 Mechanize 的 Ruby 1.9 和 2.0 中的 OpenSSL::SSL::SSLError