【问题标题】:How can I validate acceptance of one boolean or another boolean如何验证接受一个布尔值或另一个布尔值
【发布时间】:2015-07-30 23:39:16
【问题描述】:

我需要验证一个布尔值或另一个布尔值是否在表单中被接受。

我试过了

validates_acceptance_of :seller_accepted || :buyer_accepted

但这不起作用

【问题讨论】:

    标签: ruby-on-rails validation mongoid


    【解决方案1】:

    Rails 验证器是元编程宏。在评估类时读入。他们添加了一个验证规则(回调)列表,当valid? 被调用到类时要运行。

    这就是为什么您必须将 ifunless 选项与 lambda、proc 或在验证实例时实际调用的符号一起使用。

    这是您的代码无法运行的原因之一。使用ifunless 条件在这里也不起作用——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
    

    【讨论】:

    • 谢谢 Max,当我在电脑前时,我会尽快尝试。为什么你昨天从问题中删除了答案?
    • 我没有时间/精力来编辑它以便正确回答问题。
    • 哦,好吧,我想也许我说了一些冒犯的话。无论如何,再次感谢!
    • 所以我一直在使用可接受的?方法,但它返回 nil 而不是 true 或 false,即使我知道我的 val = true。对出了什么问题有任何想法吗?
    • 这很奇怪,包括?返回真/假
    猜你喜欢
    • 2014-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 2016-10-05
    • 1970-01-01
    相关资源
    最近更新 更多