【问题标题】:Validate that at least one check_box is selected in Rails (non HABTM)验证 Rails 中至少选择了一个复选框(非 HABTM)
【发布时间】:2014-03-25 05:37:20
【问题描述】:

我有一个模型请求的数据库表,其中有一列是项目。项目是一个数组。当用户提交表单时,我需要一个验证,以确保数组不为空(即,至少检查一项),然后才允许他们点击提交。

如果 item 是属于 Request 的模型,但如果 item 只是 Request 中的一个列,我已经找到了如何执行此操作。以下是我的最佳尝试,但它不起作用,因为我收到错误“您需要提供至少一个验证”

型号代码

class Request < ActiveRecord::Base
  serialize :item
  validates :must_have_one_item

  def must_have_one_item
    for item in @request.items
        errors.add(:base, 'You must select at least one item') if request.item.blank?
    end
  end

查看表单代码

<%= f.check_box(:item, {:multiple => true}, "#{item}") %>

控制器代码

def create
    @requestrecord = Request.new(request_params)
end

private
    def request_params
       params.require(:request).permit({:item => []})
    end

【问题讨论】:

  • 顺便说一句,你有item作为复选框和:item在许可中,但是在模型代码中访问items....我建议将它们都称为items以减少混乱。您正在谈论一组项目...所以将它们命名为items
  • 啊,所以我解决了这个问题,但反过来,我决定调用所有项目,因为那是数据库中的表。但正如我在下面的另一条评论中所写,self.item.blank?不会通过错误,但实际上也不会进行检查
  • 是的 - 它会在单个项目和多个项目之间混淆。最好以实际合理的方式修复它;)

标签: ruby-on-rails forms validation checkbox


【解决方案1】:

自定义验证的正确调用如下:

validate :must_have_one_item

请注意,自定义验证块是使用 validate 调用的,而不是 validates。根据the docsvalidate 执行以下操作:

向类添加验证方法或块。当覆盖 validate 实例方法变得过于笨拙并且您正在寻找更具描述性的验证声明时,这很有用。

将这与再次从the docs 调用validates 的方式进行对比:

此方法是所有默认验证器和任何以“Validator”结尾的自定义验证器类的快捷方式。

【讨论】:

    【解决方案2】:

    这将为每个空白项添加一个错误。

    def must_have_one_item
      for item in @request.items
        errors.add(:base, 'You must select at least one item') if request.item.blank?
      end
    end
    

    如果它们都是空白的,你想添加一个错误是吗?

    def must_have_one_item
      errors.add(:base, 'You must select at least one item') if self.items.all?{|item| item.blank? }    
    end
    

    或者,根据您的项目的运作方式,这也可能有效::

    def must_have_one_item
      errors.add(:base, 'You must select at least one item') if self.items.blank? 
    end
    

    【讨论】:

    • 我绝对想要你所说的后者。但是使用代码(或者),它会为 NilClass 抛出一个未定义的方法“项目”。我不确定为什么它没有响应该方法(顺便说一句,我更改为 if @requestrecord.items.blank?因为@requestrecord = Request.new per controller)
    • 所以 - 我们已经在请求中了。要获取这组项目,您无需转到@request 变量,而是使用self 来引用“我们现在正在保存的当前请求”
    • 正确正确,这完全有道理。我不想再问了,但是我仍然收到一个 items is undefined method 错误,但是对于那个特定的请求。最初我认为这是一个复数问题,所以我只用 item 替换了 items,但随后验证完全停止工作..
    • 将该列重命名为项目,它会神奇地工作;)(我希望)
    • 好的,所以我将所有内容重命名为项目,同样的事情,它没有抛出错误,但它也不起作用。不幸的是,删除序列化也无济于事......
    【解决方案3】:

    好的...发生的情况是复选框在未选中时存储在数组中为“0”,因此验证失败,因为数组在技术上不是空白的。

    当没有检查时,存储的参数是 items = ["0", "0", "0", "0"] 而不是 items=[]

    所以是这样的:

     def must_have_one_item
         errors.add(:items, 'You must select at least one item') unless self.items.detect { |i| i != "0" } 
     end
    

    【讨论】:

    • 这不可能是答案。
    猜你喜欢
    • 2011-03-13
    • 2015-11-06
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 2017-09-09
    • 1970-01-01
    • 2015-07-30
    • 2013-02-15
    相关资源
    最近更新 更多