【问题标题】:Active record find error活动记录查找错误
【发布时间】:2017-04-28 09:58:27
【问题描述】:

我有以下代码来查找列值为 $site 的最后一个条目

record = UsageHistory.last(site: $site)

但是当我运行它时,我得到一个异常

can't convert Hash into Integer (TypeError)

任何指针?

【问题讨论】:

  • 请确保接受最能解决您的问题的答案(在答案分数附近寻找复选标记)。您只能接受一个答案。通过这种方式,您可以告知社区您的问题已得到解决。

标签: ruby activerecord


【解决方案1】:

问题:

ActiveRecord::FinderMethods#last 不接受散列参数。

解决方案:

UsageHistory.where(site: $site)             # select all records matching the query
            .order(timestamp_column: :desc) # order by any timestamp column
            .first                          # take the first record (newest one)

请注意,其他两个给出的答案都会生成以下 SQL

SELECT usage_history.*
FROM usage_history
WHERE (site = your_site)
ORDER BY usage_history.id DESC
LIMIT $1

这不是您所需要的,因为id 的顺序不等于时间戳列的顺序。

我的查询将返回以下 SQL

SELECT usage_history.*
FROM usage_history
WHERE (site = your_site)
ORDER BY usage_history.timestamp_column DESC
LIMIT $1

两者都是对 DB 的单一查询,所以我更愿意保持明确。

【讨论】:

  • 使用条件+降序+first在这里效率超低。只要条件 + last 就足够了,看我的回答。
  • 另外,你知道id 自动增量字段比created_at 更常见吗?你怎么知道作者有created_at字段?
  • @Ilya 1) 你从来没有证明你的“超级低效”(还在等待)。 2)如果我有一个没有ID 列的数据库,last 会按预期在这里工作吗? 3) 如果有一个带有ID 列的数据库,但故意插入ID 较低但时间戳较高的记录,last 会在这里工作吗? 4) 我的回答 实际上 考虑了所有这些,并允许作者将其调整为任何 timestamp 列名。除非你能解决这些问题 - 甚至不要费心回复。
  • 如果表有主键(这比表有created_at 列更有可能),Last 将按预期工作。您可以阅读一些书籍或做基准测试 - 在最流行的数据库中通过主键查找总是比通过普通列更快。如果site 列被索引,那将是非常足够的差异(例如 MySQL InnoDB 在索引中包含主键)。附言顺便说一句,数据库不包含列,只有表:)
  • 我的意思是非常显着的差异,对不起我的英语:)
【解决方案2】:

TL;DR: 您正在尝试做的是:

record = UsageHistory.where(site: $site).last

长版: ActiveRecord::FinderMethods 中的“最后一个”方法不采用散列。在这种情况下,您需要使用诸如“where”之类的方法将其链接起来。 你可以阅读更多关于 ActiveRecord::FinderMethods#last 方法here

【讨论】:

  • 谢谢 - 了解
【解决方案3】:

您使用last 是错误的,此方法只需要limit 作为参数(最后N 条记录,例如last(5))。 查询后可以使用last

UsageHistory.where(site: $site).last

您也可以将find_by 与订单条件一起使用(效率较低):

Campaign.order(id: :desc).find_by(site: $site)

【讨论】:

  • 拍摄,我误读了您的第一句话并想编辑,意识到我错了,想回滚并最终(可能)弄乱了答案的版本。对不起
  • @AndreyDeineko,无论如何,谢谢,请随时让我的答案变得更好。
  • @Steve,这只是用户的选择 :) 我猜它是 100% 正确的。
猜你喜欢
  • 2014-08-05
  • 2014-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-04
  • 2016-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多