如何仅在属性存在时验证属性?

时间:2014-06-05 08:19:05

标签: ruby-on-rails validation conditional-statements proc

我有很多模型,它们之间共享许多不同的属性,因此我必须验证所有这些以及我遇到问题的地方。如果我将所有总是一起使用的属性组合在一起并将它们的验证放在一个单独的模块中,我最终会得到20个模块,这看起来似乎没有...而且我还想过将attrs验证放在2-3个模块组中它们在逻辑上,就像一个模块用于定位器,另一个用于选项等,并通过以下方式向所有IF添加条件:

validates :city,
presence: true,
length: {minimum: 5},
if: Proc.new {|p| p.respond_to?(:city)}

看起来它有效但是对每个验证方法重复这个条件比使用一堆模块更加错误,所以问题是,我该怎么做呢?

编辑: 例: 想象一下,你有3个型号:汽车,卡车和自行车及其附件:

  

汽车 - > attr_1,attr_3

     

卡车 - > attr_2,attr_3

     

自行车 - > attr_1,attr_2

所以你可以将每个attr的验证放到它的模块中并将它包含到具有这个属性的clases中,所以你不必重复它...(那就是我最终得到20个模块)或者你可以创建只有一个模块有3个验证,如下所示:

validates :attr_1, length: {minimum: 2}, if: Proc.new {|p| p.respond_to?(:attr_1)}
validates :attr_2, presence: true, if: Proc.new {|p| p.respond_to?(:attr_2)}
validates :attr_3, inclusion: {in: 1..5}, if: Proc.new {|p| p.respond_to?(:attr_3)}

这似乎更难看......所以我需要在这里找到一些妥协...

2 个答案:

答案 0 :(得分:1)

好的...所以你有多个模型,上面有一组相关的属性(和验证)>

一些选项是:

  1. 使用每个模型中包含的模块
  2. 将属性提取到自己的模型中(具有自己的属性和验证),并与每个相关模型进行多态关联
  3. 如果您使用的是最新版本的rails,请查看关注点 - 这是一种更好的做法(1)
  4. 如果真的有20组不同的东西......那就创造20个。 但是如果这些东西的组合在每个使用它们的模型中总是在一起......你可以将它们放在一起(并使用像Max的建议那样使代码缩短以便阅读)

答案 1 :(得分:1)

请记住,您只是在这里使用红宝石代码,没有任何神奇的事情发生。所以你可以做一个循环:

[:attr1, :attr2, :attr3].each do |att|
  validates att, presence: true, length: {minimum: 5}, if: Proc.new {|p| p.respond_to?(att)}
end