【问题标题】:Including a Validator class from a Concern in Rails在 Rails 中包含来自关注点的 Validator 类
【发布时间】:2019-07-28 22:31:09
【问题描述】:

我有一个自定义的EachValidator,用于两种不同的模型。我将其移至关注点以干燥模型:

module Isbn
  extend ActiveSupport::Concern

  included do
    class IsbnValidator < ActiveModel::EachValidator
      GOOD_ISBN = /^97[89]/.freeze

      def validate_each(record, attribute, value)
       # snip...
      end
    end
  end
end
class Book < ApplicationRecord
  include Isbn

  validates :isbn, allow_nil: true, isbn: true
end
class BookPart < ApplicationRecord
  include Isbn

  validates :isbn, allow_nil: true, isbn: true
end

在运行 Rails 时(在本例中是通过 RSpec),我收到以下警告:

$ bundle exec rspec
C:/Users/USER/api/app/models/concerns/isbn.rb:16: warning: already initialized constant Isbn::IsbnValidator::GOOD_ISBN
C:/Users/USER/api/app/models/concerns/isbn.rb:16: warning: previous definition of GOOD_ISBN was here

有什么办法可以避免它并在每个模型中干净地包含验证器?

【问题讨论】:

    标签: ruby-on-rails ruby activesupport activesupport-concern


    【解决方案1】:

    每次包含Isbn 模块时,它都会触发included 方法,该方法打开IsbnValidator &lt; ActiveModel::EachValidator 类并在其中创建GOOD_ISBN 常量和validate_each 方法。请注意,这些常量和方法每次都在同一个类中创建 - IsbnValidator &lt; ActiveModel::EachValidator

    所以,第一次包含 Isbn 模块时,您在 IsbnValidator &lt; ActiveModel::EachValidator 中创建了 GOOD_ISBN 常量,之后您将 Isbn 模块包含到另一个类中,included 方法尝试再次创建 GOOD_ISBN 常量IsbnValidator &lt; ActiveModel::EachValidator 显然失败了,你得到了那个错误。

    因此,您的 included 方法应如下所示:

    module Isbn
      extend ActiveSupport::Concern
    
      included do
        GOOD_ISBN = /^97[89]/.freeze
    
        def validate_each(record, attribute, value)
         # snip...
        end
      end
    end
    

    这样GOOD_ISBNvalidate_each 将为您导入Isbn 的类创建(即BookBookPart

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-07
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 2020-09-18
      • 2014-09-18
      相关资源
      最近更新 更多