简体   繁体   English

在 ActiveModel::EachValidator 中使用实例变量

[英]Using instance variables inside ActiveModel::EachValidator

I faced with curious fact (for me) about using each validators.我遇到了(对我来说)关于使用每个验证器的奇怪事实。 For example we have a some custom each validator and some model:例如,我们有一些自定义的每个验证器和一些 model:

class Thing < ApplicationRecord
  validates :field, custom: true
end

class CustomValidator < ActiveModel::EachValidator
  def validate_each(record, _attribute, _value)
    @record = record
  end
end

I've found out that an instance of CustomValidator class will be created once when we call Thing model for the first time.我发现当我们第一次调用 Thing model 时,将创建一次 CustomValidator class 的实例。 It means that we will have same validator object for every Thing instance.这意味着我们将为每个 Thing 实例拥有相同的验证器 object。 And my question is: How do you think, can we use instance variables inside validators like this or not... because looks like validator object will be created only once, and, for example, if we will call Thing.first.valid?我的问题是:你怎么看,我们是否可以在这样的验证器中使用实例变量......因为看起来验证器 object 只会创建一次,例如,如果我们将调用 Thing.first.valid? and then Thing.last.valid?然后是 Thing.last.valid? the @record will have the same value before we reassign it. @record 在我们重新分配之前将具有相同的值。

Or maybe a separate validator object will be created for each client?或者可能会为每个客户端创建一个单独的验证器 object?

I just worry is it possible that we can face races around @record variable when several widgets will be validated at the same time?我只是担心当同时验证多个小部件时,我们是否有可能面临围绕 @record 变量的竞争?

Thnx谢谢

I found another way, just define the class with a class method "validate" and an instance method "validate", and use this class method like a block.我找到了另一种方法,只需使用 class 方法“validate”和实例方法“validate”定义 class,然后像块一样使用此 class 方法。 So, we can move huge validation in class, use it shortly in model Thing, and use instance variable between validator methods因此,我们可以在 class 中移动大量验证,在 model 事物中使用它,并在验证器方法之间使用实例变量

class Thing < ApplicationRecord
  validate MyCustomValidator
end

class MyCustomValidator
  def self.validate(record)
    new(record).validate
  end

  def initialize(record)
    @record = record
  end

  def validate
    # some payload with @record
    validate_breakdowns
    validate_indicators
  end

  private

  attr_reader :record

  def validate_breakdowns
    # some payload with @record
  end

  def validate_indicators
    # some payload with @record
  end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM