【问题标题】:Rails find_by with ORRails find_by 与 OR
【发布时间】:2012-06-12 15:04:30
【问题描述】:

我在我的 Rails 应用程序中设置了一个命名范围,用于通过其 ID(直接来自索引视图)或 UUID(来自电子邮件 - 基本上只是为了让用户无法输入)来定位记录任何 ID 并查看记录)

scope :by_uuid, lambda { |id| where('id = ? OR uuid = ?', id, id) }

这个用在show action中,所以id来自url,like

services/114

services/74c083c0-8c29-012f-1c87-005056b42f8a

这很好用,直到您获得诸如 74c083c0-8c29-012f-1c87-005056b42f8a 之类的 UUID 不幸的是,rails 转换为 int 值,我们得到 services/74 以及具有正确 UUID 的记录

将 .first 添加到范围将无济于事,因为每条记录的顺序可能不同,因此不起作用。

有没有办法防止 rails 像这样转换 ID 并按字面意思获取字符串?显然,不会有一条 ID 与之匹配的记录,但如果它与传递给它的字符串的整数值无缘无故,我们可以取回任何东西。

使用动态查找器,例如

Service.find_by_uuid

Service.find_by_id

按预期工作,但是我们需要能够使用 UUID 或 ID 以相同的方法(显示)检索记录。

有没有办法做类似的事情

Service.find_by_id_or_uuid

【问题讨论】:

  • 您最初使用带有 lambda 函数的命名范围的想法应该可行。你确定你的代码没有错误吗?看起来它应该是范围:by_uuid, lambda { where('id = ? OR uuid = ?', id, uuid) } - 您在问题的参数化查询中都有 id 作为两个参数。
  • 是的,因为 id 来自 URL 字符串 - 所以我们可以有 services/114 或 services/74c083c0-8c29-012f-1c87-005056b42f8a 并且它需要同时响应这两者,我实际上离开了出|id|宣言。我编辑了上面的帖子以澄清。问题是它获取了 UUID 字符串的 int 值并提取了 services/74 而不是正确的记录。

标签: mysql ruby-on-rails-3 named-scope


【解决方案1】:

我们通过对范围的以下更改解决了这个问题:

scope :by_uuid, lambda { |id| where('binary id = ? OR uuid = ?', id, id) }

这确保了 id 字符串由其二进制值获取,而不是被转换为 int。但是,这将仅适用于基于 MYSQL 的应用程序

【讨论】:

    猜你喜欢
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多