3

我使用gem 在这样的模型acts-as-taggable-on上填充用户兴趣User

# User.rb
acts_as_taggable
acts_as_taggable_on :interests

当我填充interest_list数组时,我需要检查给定值是否与常量数组匹配,以确保这些是可接受的值,如下所示

VALID_INTERESTS = ["music","biking","hike"]
validates :interest_list, :inclusion => { :in => VALID_INTERESTS, :message => "%{value} is not a valid interest" }

上面的代码返回以下错误

@user = User.new
@user.interest_list = ["music","biking"]
@user.save
=> false …. @messages={:interest_list=>["music, biking is not a valid interest"]}

我可以看到包含没有意识到它应该迭代数组元素而不是 s 考虑作为一个普通字符串,但我不知道如何实现这一点。任何的想法?

4

3 回答 3

12

标准包含验证器不适用于此用例,因为它会检查所讨论的属性是否是给定数组的成员。您想要检查数组的每个元素(属性)是否是给定数组的成员。

为此,您可以创建一个自定义验证器,如下所示:

VALID_INTERESTS = ["music","biking","hike"]
validate :validate_interests

private

def validate_interests
  if (invalid_interests = (interest_list - VALID_INTERESTS))
    invalid_interests.each do |interest|
      errors.add(:interest_list, interest + " is not a valid interest")
    end
  end
end

通过取这两个数组的差异,我得到了interest_listnot in的元素。VALID_INTERESTS

我实际上没有尝试过这段代码,所以不能保证它会起作用,但我认为解决方案看起来像这样。

于 2012-11-27T07:55:23.937 回答
0

这是一个很好的实现,但我忘记了模型描述中的一个。

serialize : interest_list, Array
于 2018-12-20T04:55:55.667 回答
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

可以在这里找到示例:

于 2019-11-29T08:30:06.300 回答