Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails验证数组中的值_Ruby On Rails_Ruby_Postgresql_Validation_Activerecord - Fatal编程技术网

Ruby on rails Rails验证数组中的值

Ruby on rails Rails验证数组中的值,ruby-on-rails,ruby,postgresql,validation,activerecord,Ruby On Rails,Ruby,Postgresql,Validation,Activerecord,在我的计划模型中,我想向:wdays字段添加一些验证,该字段是int[]。我只希望值0..6有效 有效的 无效的 Schedule.wdays = [0,1,10] 我试着用 validates :wdays, inclusion: { in: [0, 1, 2, 3, 4, 5, 6] } 及 但两者都不起作用 验证模型中数组中的值的正确方法是什么?我认为默认Rails验证器在这里不会起作用,但您可以这样做: validate :validate_wdays def validate_w

在我的计划模型中,我想向:wdays字段添加一些验证,该字段是int[]。我只希望值0..6有效

有效的

无效的

Schedule.wdays = [0,1,10]
我试着用

validates :wdays, inclusion: { in: [0, 1, 2, 3, 4, 5, 6] }

但两者都不起作用


验证模型中数组中的值的正确方法是什么?

我认为默认Rails验证器在这里不会起作用,但您可以这样做:

validate :validate_wdays

def validate_wdays
  if !wdays.is_a?(Array) || wdays.detect{|d| !(0..6).include?(d)}
    errors.add(:wdays, :invalid)
  end
end

我不确定在现有的Rails验证结构中是否有更简单的方法来处理这个问题。你遇到了一个奇怪的情况,验证器并不是专门用来处理的。您可能需要为类似的内容编写一个自定义验证器(假设现有的验证扩展gem不可用)。大概是这样的:

class ArrayInRangeValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, valueArray)
    valueArray.each do |value|
      record.errors.add "#{attribute} - #{value}", (options[:message] || "is not in the acceptable range") unless (1..6).include?(value)
    end
  end
end
class ArrayRangeValidator
然后在您的模型中:

class Schedule < ActiveRecord::Base
    include ActiveModel::Validations

    validates :wdays, :presence => true, :array_in_range => true

    ... other model stuff
end
class Scheduletrue、:array\u in\u range=>true
... 其他模型材料
结束
我创建了这个宝石:

基本上,您可以使用以下命令:

class User < ActiveRecord::Base
   DEFAULT_PERMISSION = ["read", "write", "share"]
   validates_intersection_of :permission, in: DEFAULT_PERMISSION
end

享受吧!评论、请求和反馈总是受欢迎的。

在我看来,被接受的答案并没有真正做到这一点。如果有人将
wdays='meow'
设置为空数组
wdays=[]
而不发出警告

在该方法中,正在进行您要求的
wdays
类型转换。如果数据无效,它已经在将数据转换为数组

检查类型时,应使用类型前的日期,而不是日期


@tirdadc我从您的编辑中添加了一些更新,但是您能否验证验证器的名称必须是带下划线的版本(它应该是
array\u in_range
而不是
arrayInRange
?你知道关于该约定的任何文档吗?验证器的名称应该加下划线这不完全有效…如果有人设置
wdays='meow'
它会将其设置为空数组
[]
没有警告。如果数据无效,则堆栈上的某些内容正在将数据转换为数组
class Schedule < ActiveRecord::Base
    include ActiveModel::Validations

    validates :wdays, :presence => true, :array_in_range => true

    ... other model stuff
end
class User < ActiveRecord::Base
   DEFAULT_PERMISSION = ["read", "write", "share"]
   validates_intersection_of :permission, in: DEFAULT_PERMISSION
end
user = User.new(permission: ["read", "share"])
user.valid? #true

user = User.new(permission: ["read", "admin"])
user.valid? #false
validate :validate_wdays

def validate_wdays
  errors.add(:wdays, :invalid) if wdays_changed? && !wdays_before_type_cast.is_a?(Array)
  errors.add(:wdays, :invalid) if wdays.any? { |d| (0..6).exclude?(d) }
end