我如何验证接受一个布尔值或另一个布尔值
How can I validate acceptance of one boolean or another boolean
我需要验证表单中接受了一个布尔值还是另一个布尔值。
我试过了
validates_acceptance_of :seller_accepted || :buyer_accepted
但这不起作用
Rails 验证器是元编程宏。在评估 class 时读入。当 valid?
被调用到 class.
时,他们添加了一个验证规则列表(回调)为 运行
这就是为什么您必须将 if
和 unless
选项与 lambda、proc 或验证实例时实际调用的符号一起使用。
这就是您的代码无法运行的原因之一。使用 if
或 unless
条件在这里也不起作用 - Rails 会在计算 if: :buyer_accepted
.
之前向 seller_accepted
添加错误
在这种情况下,最干净的解决方法可能是创建自定义验证方法:
validate :one_of_two_accepted
def one_of_two_accepted
unless acceptable?(seller_accepted) || acceptable?(buyer_accepted)
errors.add(:seller_accepted, "Must accept buyer or seller.")
end
end
def acceptable?(val)
['1', true, 'yes'].include?(val)
end
acceptable?
方法模拟了 validates_acceptance_of
完成的类型转换。
编辑。
这是完整的、最小的、经过验证的示例:
class Thing < ActiveRecord::Base
attr_accessor :seller_accepted
attr_accessor :buyer_accepted
validate :one_of_two_accepted
def acceptable?(val)
['1', true].include?(val)
end
def one_of_two_accepted
unless acceptable?(seller_accepted) || acceptable?(buyer_accepted)
errors.add(:seller_accepted, "Must accept buyer or seller.")
end
end
end
require 'rails_helper'
RSpec.describe Thing, type: :model do
let(:thing) { Thing.new }
describe 'acceptable?' do
it "accepts '1'" do
expect(thing.acceptable?('1')).to be_truthy
end
it "accepts 'true' " do
expect(thing.acceptable?(true)).to be_truthy
end
it "rejects others" do
expect(thing.acceptable?('gobbeligook')).to be_falsy
expect(thing.acceptable?('no')).to be_falsy
expect(thing.acceptable?(nil)).to be_falsy
expect(thing.acceptable?(0)).to be_falsy
end
end
describe 'custom validation' do
it 'is invalid if neither seller or buyer is accepted' do
expect(thing.valid?).to be_falsy
expect(thing.errors[:seller_accepted]).to include "Must accept buyer or seller."
end
it 'is valid if seller_accepted' do
thing.seller_accepted = true
thing.valid?
expect(thing.errors).to_not have_key :seller_accepted
end
it 'is valid if buyer_accepted' do
thing.buyer_accepted = true
thing.valid?
expect(thing.errors).to_not have_key :seller_accepted
end
end
end
我需要验证表单中接受了一个布尔值还是另一个布尔值。
我试过了
validates_acceptance_of :seller_accepted || :buyer_accepted
但这不起作用
Rails 验证器是元编程宏。在评估 class 时读入。当 valid?
被调用到 class.
这就是为什么您必须将 if
和 unless
选项与 lambda、proc 或验证实例时实际调用的符号一起使用。
这就是您的代码无法运行的原因之一。使用 if
或 unless
条件在这里也不起作用 - Rails 会在计算 if: :buyer_accepted
.
seller_accepted
添加错误
在这种情况下,最干净的解决方法可能是创建自定义验证方法:
validate :one_of_two_accepted
def one_of_two_accepted
unless acceptable?(seller_accepted) || acceptable?(buyer_accepted)
errors.add(:seller_accepted, "Must accept buyer or seller.")
end
end
def acceptable?(val)
['1', true, 'yes'].include?(val)
end
acceptable?
方法模拟了 validates_acceptance_of
完成的类型转换。
编辑。
这是完整的、最小的、经过验证的示例:
class Thing < ActiveRecord::Base
attr_accessor :seller_accepted
attr_accessor :buyer_accepted
validate :one_of_two_accepted
def acceptable?(val)
['1', true].include?(val)
end
def one_of_two_accepted
unless acceptable?(seller_accepted) || acceptable?(buyer_accepted)
errors.add(:seller_accepted, "Must accept buyer or seller.")
end
end
end
require 'rails_helper'
RSpec.describe Thing, type: :model do
let(:thing) { Thing.new }
describe 'acceptable?' do
it "accepts '1'" do
expect(thing.acceptable?('1')).to be_truthy
end
it "accepts 'true' " do
expect(thing.acceptable?(true)).to be_truthy
end
it "rejects others" do
expect(thing.acceptable?('gobbeligook')).to be_falsy
expect(thing.acceptable?('no')).to be_falsy
expect(thing.acceptable?(nil)).to be_falsy
expect(thing.acceptable?(0)).to be_falsy
end
end
describe 'custom validation' do
it 'is invalid if neither seller or buyer is accepted' do
expect(thing.valid?).to be_falsy
expect(thing.errors[:seller_accepted]).to include "Must accept buyer or seller."
end
it 'is valid if seller_accepted' do
thing.seller_accepted = true
thing.valid?
expect(thing.errors).to_not have_key :seller_accepted
end
it 'is valid if buyer_accepted' do
thing.buyer_accepted = true
thing.valid?
expect(thing.errors).to_not have_key :seller_accepted
end
end
end