如何验证rails中包含数组内容

时间:2015-10-05 04:41:52

标签: ruby-on-rails arrays validation

我的模型中有一个数组列:

t.text :sphare, array: true, default: []

我想验证它只包含列表中的元素(“好”,“坏”,“中立”)

我的第一次尝试是:

 validates_inclusion_of :sphare, in: [ ["Good"], ["Bad"], ["Neutral"] ]

但是当我想在sphare ex([“Good”,“Bad”]中创建具有多个值的对象时,验证器将其剪切为[“Good”]。

我的问题是:

如何编写一个验证,只检查传递的数组的值,而不将其与修复示例进行比较?

编辑我的FactoryGirl的已添加部分并测试failds:

FactoryGirl的一部分:

sphare ["Good", "Bad"]

和我的rspec测试:

  it "is not valid with wrong sphare" do
    expect(build(:skill, sphare: ["Alibaba"])).to_not be_valid
  end
 it "is valid with proper sphare" do
    proper_sphare = ["Good", "Bad", "Neutral"]
    expect(build(:skill, sphare: [proper_sphare.sample])).to be_valid
  end  

2 个答案:

答案 0 :(得分:1)

这样做:

validates :sphare, inclusion: { in: ["Good", "Bad", "Neutral"] }

或者,您可以通过使用创建字符串数组的简短形式来表达:%w(Good Bad Neutral)

validates :sphare, inclusion: { in: %w(Good Bad Neutral) }

有关inclusion的更多用法和示例,请参阅Rails Documentation

更新

由于Rails内置验证器不符合您的要求,您可以在模型中添加自定义验证器,如下所示:

validate :correct_sphare_types

private

def correct_sphare_types
  if self.sphare.blank?
    errors.add(:sphare, "sphare is blank/invalid")
  elsif self.sphare.detect { |s| !(%w(Good Bad Neutral).include? s) }
    errors.add(:sphare, "sphare is invalid")
  end
end

答案 1 :(得分:0)

您可以实现自己的ArrayInclusionValidator

# app/validators/array_inclusion_validator.rb
class ArrayInclusionValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    # your code here

    record.errors.add(attribute, "#{attribute_name} is not included in the list")
  end
end

在模型中,它看起来像这样:

# app/models/model.rb
class YourModel < ApplicationRecord
  ALLOWED_TYPES = %w[one two three]
  validates :type_of_anything, array_inclusion: { in: ALLOWED_TYPES }
end

示例可以在这里找到