ruby-on-rails - 在 ActiveModel::EachValidator 中使用实例变量
问题描述
我遇到了(对我来说)关于使用每个验证器的奇怪事实。例如,我们有一些自定义的 each 验证器和一些模型:
class Thing < ApplicationRecord
validates :field, custom: true
end
class CustomValidator < ActiveModel::EachValidator
def validate_each(record, _attribute, _value)
@record = record
end
end
我发现当我们第一次调用 Thing 模型时,会创建一次 CustomValidator 类的实例。这意味着我们将为每个 Thing 实例拥有相同的验证器对象。我的问题是:你怎么看,我们能不能像这样在验证器中使用实例变量......因为看起来验证器对象只会被创建一次,例如,如果我们调用 Thing.first.valid?然后是 Thing.last.valid?@record 在我们重新分配之前将具有相同的值。
或者可能会为每个客户端创建一个单独的验证器对象?
我只是担心当同时验证多个小部件时,我们是否有可能面临围绕 @record 变量的竞争?
谢谢
解决方案
我找到了另一种方法,只用一个类方法“validate”和一个实例方法“validate”来定义类,并像块一样使用这个类方法。因此,我们可以在类中移动大量验证,在模型事物中使用它,并在验证器方法之间使用实例变量
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
推荐阅读
- regex - 替换文件中的分隔符而不更改引号之间的值
- android - WiFi网络连接在Android Q上不断断开
- graphql - 如何使用 Apollo 客户端 websocket 处理注销/登录并保持有效订阅?
- python-3.x - 根据来自其他数据框 pandas 的信息添加列
- javascript - Ajax 问题基于类别在 foreach 内加载更多 CPT 循环请求
- c++ - 从 CMake 中的 lib 目录加载共享库?
- mysql - 从本地机器(Ubuntu 14.04 LTS)推入 docker 时出现 mysql 问题
- javascript - Coldfusion websocket在将ws更改为wss协议时无法创建websocket握手
- c++ - 将函数指针数组中的函数指针作为模板参数传递
- sql-server - 如何将动态多个输入值传递给 SQL Server 2014 中的 LIKE 运算符?