这个验证几乎是正确的吗?

时间:2011-12-03 04:10:36

标签: ruby-on-rails ruby validation

我有一个表格,学生正在使用这个表格从1到6排名6个班级。如果他们选择数学为“1”(最难),那么我不希望他们能够选择另一个主题作为最难的。表格显然会让他们为每个主题选择“1”,但我想使用验证来防止提交不遵循指示的表格

这是表格

的摘录
<div class="field">
    <%= f.label(:math, "Mathp") %>
    <%= f.select:math, 1..6 %> </br>
    </div>

<div class="field">
    <%= f.label(:french, "French") %>
    <%= f.select:french, 1..6 %> </br>
    </div>

我打算使用这样的验证方法,但我认为它的逻辑不起作用(即它不能防范所有可能的情况)并且它可能也是糟糕的(非功能性)代码,因为我只是在学习如何编码(实际上我已经失败了很长一段时间了)。你能建议改进吗?

validates :rank_favorites 


...

def rank_favorites

unless :math != :french && :french != :history && :history != :spanish && :spanish != :art && :art != :physed return false

end

3 个答案:

答案 0 :(得分:3)

可悲的是,你的rank_favorites已经过时了,但无知可以通过学习来解决。你只是在比较一堆符号,并没有做任何有用的事情(至少没有你所关注的那样),你的验证器会减少到这个:

unless false && false && false && false && false return false

相当于:

unless false return false

你可能想要使用validate :rank_favorites(不是validates)而你的验证器会add error messages而不是简单地返回一个布尔值:

validate :rank_favorites

#...

def rank_favorites
  ranks = [math, french, history, spanish, art, physed]
  if(ranks.include?(nil))
    errors[:base] << 'Rank all of them you lazy person!'
  elsif(ranks.uniq.length != ranks.length)
    errors[:base] << 'You fail at ranking, no duplicates allowed.'
  end
end

Array#uniq方法将生成一个数组的副本,并删除重复项,如果长度不匹配则删除了一些内容并且您有重复的条目。

您可能需要花一些时间阅读验证指南:

  

Active Record Validations and Callbacks

答案 1 :(得分:1)

您可以随时执行以下操作:

validate do
  unless [math, french, history, spanish, art, physed].uniq.length == 6
    errors.add(:base, :doh_theyre_not_unique_error)
  end
end

这真的感觉它可以使用一些JS形式的爱。

答案 2 :(得分:1)

所以你真正想做的是确保没有主题获得相同的排名:)

:math != :french # => true ALWAYS because they internalized constant strings which are obviously different

如果你这样做..

self.math != self.french # => this is comparing variables now. much better. BUT Still wrong in terms of the logic you want

怎么样

if [self.math,self.french,self.history,self.spanish,self.art,self.physed].uniq.sort != [1,2,3,4,5,6])
  errors.add(:base,"Repeated rankings")
end