Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #11338 (closed enhancement: fixed)

Opened 9 months ago

Last modified 9 months ago

[PATCH] Add find(:last) to ActiveRecord Base

Reported by: miloops Assigned to: core
Priority: normal Milestone: 2.x
Component: ActiveRecord Version: edge
Severity: normal Keywords: find
Cc:

Description

I know there as been some attempts to add this functionality like in http://dev.rubyonrails.org/ticket/3950. I try to solve this problem with this patch.

If no order is given:

User.find(:last)

The primary_key will be reverted in the query using DESC.

And if any order option is given, i use regexps to change any ASC to DESC and vice versa. And in case no specific order is given to a column_name DESC is added, because the default would be ASC ("payments.amount, payments.date DESC" would be "payments.amount DESC, payments.date ASC"). This way, the SQL query will have a limit one, so instead doing a heavy query, then instantiating all the objects, and then using only the last one, you will only query for the last element.

After reversing the order i just call find_initial like find(:first) does, i think is a DRY-way to do it.

Documentation and tests included.

Attachments

add_last_option_to_active_record_base_find.diff (4.7 kB) - added by miloops on 03/12/08 19:47:49.

Change History

(follow-up: ↓ 2 ) 03/12/08 16:58:34 changed by DefV

Small doc-remark: Update base.rb line 433 to

# Find operates with four different retrieval approaches:

four instead of three

As for the rest great patch! Big +1

(in reply to: ↑ 1 ) 03/12/08 17:34:08 changed by miloops

Replying to DefV:

Small doc-remark: Update base.rb line 433 to {{{ # Find operates with four different retrieval approaches: }}} four instead of three As for the rest great patch! Big +1

Thanks you!!! Doc changed to "...four different retrieval approaches"

03/12/08 19:47:49 changed by miloops

  • attachment add_last_option_to_active_record_base_find.diff added.

(follow-up: ↓ 5 ) 03/12/08 20:30:12 changed by matt

Can you please confirm that what you do is just reversing the order on the primary key?

last = Developer.find :last assert_equal last, Developer.find(:first, :order => 'id desc')

Thanks,

-Matt

03/12/08 20:36:07 changed by david

I really like the feature, but I really don't like the munging of the ORDER SQL to achieve it. It feels too clever. I don't think it makes sense to use :last when you're explicitly controlling the :order. This should just be a shortcut for when you don't bother to specify the explicit :order.

(in reply to: ↑ 3 ) 03/12/08 20:38:17 changed by miloops

Replying to matt:

Can you please confirm that what you do is just reversing the order on the primary key? last = Developer.find :last assert_equal last, Developer.find(:first, :order => 'id desc') Thanks, -Matt

Hey Matt, as you can see in the code if you don't specify any order or has a scoped order (with_order) the "default" order will be: "#{table_name}.#{primary_key} DESC"

03/12/08 21:26:05 changed by david

  • status changed from new to closed.
  • resolution set to fixed.

(In [9012]) Added ActiveRecord::Base.find(:last) (closes #11338) [miloops]

03/13/08 00:41:17 changed by wesley.moxam

Oh god, why???

03/13/08 00:53:37 changed by matt

David, I have to say that I'm a bit surprised that after your comment you still added the patch.

Would you mind explaining why you changed your mind?

-Matt

03/13/08 01:37:17 changed by david

Because I realized that the rewriter serves a valuable purpose for when you're dealing with scopes. So using person.comments.find(:last) when person has_many :comments, :order => "created_at" actually does make a lot of sense. The fact that it rewrites also in the case of find(:last, :order) is more accidental and for completeness. It's not actually how it's intended for use.

03/13/08 06:21:20 changed by blj

find(:last) right, what next? I wonder.

03/20/08 23:49:51 changed by trevorturk

I realize this is a closed issue, but I just wanted to say that I'm glad to have this feature. Actually, I had tried to use it in the past and was surprised to find it missing :)