我的控制器中有以下代码:
@items = Item.where(:user_id => 1).order("updated_at DESC").limit(2)
@oldest_item = @items.last
出于某种原因,我猜这与我最近升级到Rails 3有关,@ oldest_item没有被设置为@items中的最后一项,而是被设置为匹配的最后一项{ {1}}。
所以想象有3个项目匹配,A,B和C. @items被设置为[A,B],然后@oldest_item被设置为C.
奇怪的是,当我在视图中调用Item.where(:user_id => 1).order("updated_at DESC")
时,它正确地返回B.
当我将控制器中的两行粘贴到控制台时,它也会正确返回B.
有人可以向我解释这里到底发生了什么事吗?
答案 0 :(得分:5)
出于某种原因,ActiveRecord :: Relation忽略了limit
选项。
在Rails 3中,ActiveRecord实际上不会执行您的查询,直到需要访问结果。调用last
执行此操作(但同样,忽略限制)。
您可以通过在查询中调用all
来告诉ActiveRecord执行查询。然后,当您在其上运行last
时,它会为您提供您正在寻找的“最后”记录。
@items = Item.where(:user_id => 1).order("updated_at DESC").limit(2)
# @items is an ActiveRecord::Relation here
@oldest_item = @items.last
# Returns "C" instead of "B". This is actually ignoring the `limit` parameter
@items = Item.where(:user_id => 1).order("updated_at DESC").limit(2).all
# @items is an Array of ActiveRecord objects here
@oldest_item = @items.last
# Returns "B"
这对我来说似乎不是预期的行为。我在rails issues tracker中提交了一个错误。
更新:@BaroqueBobcat提交了一个patch已被接受,因此应该在即将发布的Rails 3.1版本中修复。
答案 1 :(得分:0)
我正在使用Rails 6,并且遇到类似的问题。我在记录上使用了reload从数据库中重新加载了它。
account = Account.new
# => #<Account id: nil, email: nil>
account.id = 1
account.reload
# Account Load (1.2ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT 1 [["id", 1]]
# => #<Account id: 1, email: 'account@example.com'>