【问题标题】:exists? Ruby Postgresql Active Record Validation with multiple conditions存在吗?具有多个条件的 Ruby Postgresql 活动记录验证
【发布时间】:2020-01-17 17:45:29
【问题描述】:

我想,比较这两个参数是否存在于数据库中相同的注册ID。

例子:

Data.all 返回这个。

phone_number | adress
12345678     | route 66

检查以下是否为所有参数返回 true。

我的如果有活动记录:

 if Data.exists?(phone_number: "#{params["phone_number"]}", adress: "#{params["adress"]}")
   puts "true, it's registered"

 else
  puts "false not, registered."
  Data.create!(phone_number: "#{params["phone_number"]}", adress: "#{params["adress"]}")

 end

如果以上为两个参数中的新选择返回 false

示例:

Data.all 返回这个。

phone_number | adress
95654152   | route 67

使用参数创建一个新的寄存器,而不是重复。

你能帮帮我吗?正如我写的那样,它只验证 1 个条件,而不是 2 个参数。

【问题讨论】:

  • 第一个Data.all和第二个显示的电话号码和地址不同
  • 当然,如果条件检查的参数与表数据不同,则插入其他数据,只比较两个参数而不插入。
  • 你能展示一个可重现的例子来说明它是如何不工作的吗?您的代码没有明显的问题,因此请务必检查您作为参数传递给 .exists? 的确切值,并将它们与数据库值进行比较。
  • 当我执行原始代码时,它只比较 1 个值与获得 2 个值的结果最终创建一条新记录,因为在比较第一个值是否存在而第二个值不存在时创建,我正在尝试仅在 2 个值不存在时验证他必须创建新记录。

标签: ruby-on-rails ruby postgresql activerecord


【解决方案1】:

使用活动记录#find_or_create_by。你可以在这里查看文档https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_create_by

Data.find_or_create_by(phone_number: params[:phone_number], adress: params[:adress])

【讨论】:

  • 你不需要字符串插值。而且 apidock 不是官方文档。
【解决方案2】:

一个简单的解决方案可能是使用ActiveRecord#find_or_create_by 方法,该方法返回现有记录,如果不存在则生成新记录:

Data.find_or_create_by(phone_number: params["phone_number"], adress: params["adress"])

请注意,在这种情况下不需要使用字符串插值 ("#{ ... }")。甚至更短:

Data.find_or_create_by(params.permit(:phone_number, :adress))

但是当你真的需要确保数据库中永远不会有相同的记录时,你应该确保在模型和数据库中也是如此。

我建议在模型中添加uniqueness validation

# in app/models/data.rb
validates :phone_number, uniqueness: { scope: :adress, case_sensitive: false }

一个unique index到数据库

add_index :datas, [:phone_number, :adress], unique: true

验证索引的组合确保即使您忘记在另一个控制器中使用find_or_create或通过另一个渠道将数据导入数据库,您也不会在数据库中出现重复.

【讨论】:

  • 更优雅的方式是Data.find_or_create_by(params.slice(:phone_number, :adress))。在 Ruby 中手动将哈希键复制到一个新的哈希值是愚蠢的。
  • 嗨@max,恕我直言find_or_create_by 期望参数被允许,并在传入未经允许的参数时引发错误。因此,在这种情况下,我认为permit 是比slice 更好的选择。为什么你更喜欢slice 而不是permit
  • 是的,许可证是更好的选择。
猜你喜欢
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
  • 2018-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-18
  • 1970-01-01
相关资源
最近更新 更多