Rails 仅当输入与动态数组中的字符串匹配时才进行验证

Rails validation only if input matches a string from a dynamic array

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

我的交易控制器中的路由是autocomplete_names

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

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

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

这是错误的,无法正常工作,所以我需要弄清楚要在“:in”中放入什么进行验证

Transaction 中创建一个 class 方法,它将 return 名称数组。然后在validates_inclusion_of.

中调用这个方法

添加一个 class 方法,它应该类似于

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

根据文档,

The :allow_blank option is similar to the :allow_nil option. This option will let validation pass if the attribute's value is blank?, like nil or an empty string for example.

从验证中删除 allow_blank 选项。您的验证应该类似于

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

更新答案

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

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,我相信上述验证结构是最新的。

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

这里您需要在 Transaction class 中使用一个方法,该方法将 return 您想要验证是否包含 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 ->。如果您不使用它,则仅在 class 定义时评估字符串数组。但是每次 运行 此验证时,您都需要来自数据库的实际数据。所以,我猜它应该是一个 lambda。不确定语法。请试一试。

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