【问题标题】:Rails validation only if input matches a string from a dynamic array仅当输入与动态数组中的字符串匹配时才进行 Rails 验证
【发布时间】:2016-12-22 08:42:34
【问题描述】:

我有一个接受 Bill 模型输入的表单。该表单具有自动完成功能,可为您提供在 Transactions 模型中创建的动态数组中的单词。我想做一个只允许数组中的单词作为输入的验证。我找到了验证 validates_inclusion_of 但我不确定这是否是正确的验证以及如何链接模型中的验证以检查为自动完成创建的数组。

我的 Transactions 控制器中的路由是 autocomplete_names

如何在我的 Transactions 控制器中根据路由对输入进行验证检查。

这是我目前进行的验证,还是我在错误的上下文中使用它并需要进行自定义验证?

validates_inclusion_of :my_bill, in: [Transaction::autocomplete_names], :allow_blank => true, message: "Bill name not found in your account, please try again"

这是错误的并且不起作用,所以我需要弄清楚在“:in”中放入什么来进行验证

【问题讨论】:

  • 你使用的是什么版本的 Rails?
  • 我使用的是 Rails 4.0.10
  • 当你在 Rails 控制台中输入Transaction::autocomplete_names 时,输出是什么?
  • 错了,autocomplete_names 是我的 Transaction 控制器中的一个动作。我需要它在字符串数组中查找子字符串。因此,例如 my_bill 可以是“directv”,它会通过我的 Transaction 模型 trans_name 字段进行查看,该字段是一个字符串数组,并检查它们是否是与该输入匹配的任何子字符串。我使用控制器操作在数组上调用我的自动完成功能,并认为我可以在验证中使用相同的操作。但我可能错了。
  • 在您的验证中,Transaction::autocomplete_names 命令正在您的Transaction 模型中查找函数。您可以在模型中编写一个函数,从数据库列:trans_name 输出一个数组。

标签: ruby-on-rails validation autocomplete mongoid


【解决方案1】:

Transaction 中创建一个类方法,它将返回名称数组。然后在validates_inclusion_of调用这个方法。

添加一个看起来像这样的类方法

def self.autocomplete_names
  # return an array of words matching bills associated with the user's account
end

然后在验证中使用它。

validates_inclusion_of :my_bill, in: Transaction.autocomplete_names

从文档中,

:allow_blank 选项类似于 :allow_nil 选项。如果属性的值为空,此选项将使验证通过?例如 nil 或空字符串。

从验证中删除allow_blank 选项。您的验证应如下所示

validates_inclusion_of :my_bill, in: Transaction.autocomplete_names, message: "Bill name not found in your account, please try again"

【讨论】:

    【解决方案2】:

    更新答案

    您可以在 Transaction 模型中编写以下内容:

    def self.autocompete_names
        Transaction.all.pluck(:trans_name)
    end
    

    然后在您的 Bill 模型中,您可以使用以下验证:

    validates :my_bill, inclusion: { in:          Transaction.autocomplete_names,
                                     allow_blank: true,
                                     message:     "Bill name not found in your account, please try again" }
    

    由于您使用的是 Rails 4,我相信上述验证结构是最新的。

    【讨论】:

      【解决方案3】:

      您不能使用控制器操作进行验证。控制器操作用于操作数据并返回响应。它们与模型中定义的方法不同。

      在这里,您需要在 Transaction 类中使用一个方法,该方法将返回您要验证包含 my_bill 的字符串数组。像这样的:

      class Transaction
        def self.autocomplete_names
          # return that array of strings
        end
      end
      

      Bill 中,您需要将验证修改为:

      class Bill
        validates_inclusion_of :my_bill,
                               in: -> { Transaction::autocomplete_names },
                               allow_blank: true,
                               message: "Bill name not found in your account, please try again"
      end
      

      请注意在验证中使用 lambda ->。如果您不使用它,则字符串数组将仅在类定义时进行评估。但是您每次运行此验证时都需要数据库中的实际数据。所以,我猜它应该是一个 lambda。不确定语法。请试一试。

      如果您不希望将空白值存储在 my_bill 的数据库中,也可以删除 allow_blank 部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-06
        • 2021-09-03
        • 2013-02-11
        • 1970-01-01
        • 1970-01-01
        • 2018-01-04
        相关资源
        最近更新 更多