Rails 3 “last” method is returning incorrect result from ActiveRecord output

邮差的信 提交于 2019-12-24 00:07:25

问题


I've got the following code in my controller:

@items = Item.where(:user_id => 1).order("updated_at DESC").limit(2)
@oldest_item = @items.last

For some reason, and I'm guessing this has to do with my recent upgrade to Rails 3, @oldest_item is not being set to the last item in @items, but is instead being set to the last item that matches Item.where(:user_id => 1).order("updated_at DESC").

So imagine there are 3 items that match, A, B, and C. @items is being set to [A, B], and then @oldest_item is being set to C.

Oddly, when I call @items.last from within my view, it is properly returning B.

When I paste in the two lines from my controller into the console, it also properly returns B.

Can someone explain to me what the heck is going on here?


回答1:


For some reason, ActiveRecord::Relation is ignoring the limit option.

In Rails 3, ActiveRecord doesn't actually execute your query until need to access the results. Calling last does this (but again, ignores the limit).

You can tell ActiveRecord to execute the query by calling all on your query. Then, when you run last on that, it'll give you the "last" record you're looking for.

@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"

This doesn't seem like expected behavior to me. I've filed a bug in the rails issues tracker.

Update: @BaroqueBobcat submitted a patch which got accepted, so it should be fixed in the upcoming 3.1 release of Rails.




回答2:


I'm using Rails 6 and had a similar issue. I used reload on my record to reload it from the database.

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'>


来源:https://stackoverflow.com/questions/5864046/rails-3-last-method-is-returning-incorrect-result-from-activerecord-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!