内置的 Rails 方法来验证 PostgreSQL Array[String] 字段中至少有一个项目?

Built-in Rails way of validating that a PostgreSQL Array[String] field has at least one item in it?

提问人:Alien 提问时间:8/9/2023 最后编辑:Alien 更新时间:8/9/2023 访问量:44

问:

我们有一个 PostgreSQL 数组字符串字段,基本上是这样的:

add_column :books, :tags, :string, array: true, default: []

如何添加验证以验证该数组中至少有 1 个字符串,以及该字符串是否来自一组字符串?tags

我看到我们有字符串值,如下所示:accept

class Person < ApplicationRecord
  validates :terms_of_service, acceptance: { accept: 'yes' }
  validates :eula, acceptance: { accept: ['TRUE', 'accepted'] }
end

但是在 array[string] 字段上呢?这样的事情是我最好的选择吗?

class Book < ApplicationRecord
  # tags :string is an Array
  validate :tags_has_one_from_set

  enum tag: {
    foo: 'foo',
    bar: 'bar'
  }

  def tags_has_one_from_set
    allowed_tags = Book.tags.values

    if tags.length == 0
      errors.add(:tags, "Must select at least one tag")
    elsif !tags.all? { |t| allowed_tags.include?(t) }
      errors.add(:tags, "Must select from approved tag list")
    end
  end
end

在 Rails 中,有没有更多的“内置”或最佳实践方法可以做到这一点?

Ruby-on-Rails 验证

评论


答:

1赞 smathy 8/9/2023 #1

您应该能够使用内置和验证器:lengthinclusion

validates :tags,
  length: { minimum: 1, message: "must have at least one tag" },
  inclusion: { in: tags.values, message: "must be selected from: #{tags.values.join ", "}" }

评论

0赞 smathy 8/9/2023
不,它是在类上下文中执行的,因此指的是返回哈希的枚举帮助程序。tags
0赞 dbugger 8/9/2023
假设 rails 处理名称冲突:)
1赞 smathy 8/9/2023
实例与类 - 没有冲突,但我同意该方法在何处/为什么起作用并不明显。老实说,我通常有一个常量值,然后用 like 设置我的枚举 - 因为它是 DRYer/cleaner,然后我显然只会在验证中使用。Hash[ TAGS.map {|t| [t,t]} ]TAGS