Rails 4: LinkValidator 的未定义方法“facebook_copy_link”

Rails 4: undefined method `facebook_copy_link' for LinkValidator

在我的 Rails 4 中,我有一个 Post 模型,我需要对其实施自定义验证。

根据建议in this question and in the documentation here,我实现了以下代码:

#app/validators/link_validator.rb

class LinkValidator < ActiveModel::Validator
  def validate(record)
    if record.format == "Link"
      unless facebook_copy_link(record.copy)
        record.errors[:copy] << 'Please make sure the copy of this post includes a link.'
      end
    end
  end
end

#post.rb
class Post < ActiveRecord::Base
  [...]
  include ActiveModel::Validations
  validates_with LinkValidator
  [...]
end

——————

UPDATEfacebook_copy_link方法定义如下:

class ApplicationController < ActionController::Base
  [...]
  def facebook_copy_link(string)
    require "uri"
    array = URI.extract(string.to_s)
    array.select { |item| item.include? ( "http" || "www") }.first
  end
  [...]
end

——————

当我 运行 应用程序时,出现以下错误:

NameError at /posts/74/edit
uninitialized constant Post::LinkValidator
validates_with LinkValidator

知道这里出了什么问题吗?

——————

更新 2:我忘记重启服务器了。

现在,我收到一个新错误:

NoMethodError at /posts/74
undefined method `facebook_copy_link' for #<LinkValidator:0x007fdbc717ba60 @options={}>
unless facebook_copy_link(record.copy)

有没有办法在验证器中包含这个方法?

除了是 Rails 验证者 class,LinkValidator 也是 Ruby class。所以你几乎可以在上面定义任何方法。

facebook_copy_link 似乎没有使用控制器实例的状态,因此您可以轻松地将方法移动到验证器中 class:

require "uri"

class LinkValidator < ActiveModel::Validator
  def validate(record)
    if record.format == "Link"
      unless facebook_copy_link(record.copy)
        record.errors[:copy] << 'Please make sure the copy of this post includes a link.'
      end
    end
  end

  private

  def facebook_copy_link(string)
    array = URI.extract(string.to_s)
    array.select { |item| item.include? ( "http" || "www") }.first
  end
end

请注意我是如何将 facebook_copy_link 方法设为私有的。这是一个很好的做法,因为其他对象访问的唯一方法是 validate.

作为旁注,没有必要将 include ActiveModel::Validations 放入 ActiveRecord subclass 中。验证已在 ActiveRecord classes.

中可用