This project is archived and is in readonly mode.
Add limit functionality to find first and last
Reported by Stephen Celis | December 12th, 2009 @ 04:42 PM
The convenience methods .first
and
.last
on ActiveRecord::Base
have had me
itching to pass in an integer limit as you can with
Array#first
and #last
. E.g.,
array = [1, 2, "buckle", :my, Shoe]
array.first # => 1
array.first(2) # => [1, 2]
array.first(1) # => [1]
array.last(2) # => [:my, Shoe]
Attached is a patch that adds this functionality.
Person.first # => #<Person id: 1>
Person.first(2) # => [#<Person id: 1>, #<Person id: 2>]
Person.first(1) # => [#<Person id: 1>]
Person.last(2) # => [#<Person id: 49>, #<Person id: 50>]
Considerations:
ActiveRecord::Base subclasses are not kinds of Array, but named scopes and association proxies come closer. Consider the following:
>> Person.scoped({}).first # SELECT * FROM `people` LIMIT 1
=> #<Person>
>> Person.scoped({}).first(2) # SELECT * FROM `people`
=> [#<Person>, #<Person>]
The first gets special treatment. The second does not. In order
to make the second consistent, it only makes sense to add the
behavior to ActiveRecord::Base
as well. (Named scope
functionality requires additions to this patch, but I'd prefer a
consensus before making any more changes.)
Additionally, it made the most sense to add logic through to
@ActiveRecord.find_initial@, rather than merely to the convenience,
surface methods, but this obviously could cause problems for those
who have been blindly passing options hashes to
find(:first)
and :last
that include a
:limit
. I'm open to the idea of a less-invasive
approach that merely adds the functionality to the convenience
methods, but this seemed less desirable and messier.
If this is of interest to others, it could also be added to
ActiveResource::Base
.
Comments and changes to this ticket
-
Stephen Celis December 12th, 2009 @ 04:44 PM
- Tag changed from activerecord, finder, find_first, find_last, limit to activerecord, finder, find_first, find_last, limit, patch
-
Stephen Celis December 14th, 2009 @ 03:39 AM
- no changes were found...
-
Ryan Bigg October 11th, 2010 @ 12:09 PM
- Tag cleared.
- Importance changed from to Low
Automatic cleanup of spam.
-
Aditya Sanghi October 13th, 2010 @ 06:13 PM
- State changed from new to resolved
@Stephen, this functionality is now already in place in Rails 3.0.0. Marking this ticket as resolved. Feel free to comment, if you think otherwise.
-
Stephen Celis October 13th, 2010 @ 11:43 PM
Does not appear to be in place in 3.0.0:
% rails c Loading development environment (Rails 3.0.0) ruby-1.9.2-p0 > User.first 2 User Load (0.2ms) SELECT
users. FROMusers
=> [] ruby-1.9.2-p0 > User.last 2 User Load (0.3ms) SELECTusers
. FROMusers
=> [] -
Stephen Celis October 13th, 2010 @ 11:44 PM
That is, the SQL query is not limited. Please re-open or change to a different state than "resolved."
-
Ryan Bigg October 13th, 2010 @ 11:47 PM
- State changed from resolved to open
I can verify this issue exists on Rails 3.
-
Aditya Sanghi October 14th, 2010 @ 06:23 AM
@stephen, patch also does not apply cleanly anymore since there has been much refactoring around ARel.
I misread the second half of your OP and looked on the net result ( which works ) but the query does not since it does not use limit but gets all and then pick n from array.
Feel free to submit another patch.
-
Elad Meidar October 14th, 2010 @ 03:26 PM
Makes sense that the Rails default would fetch all and select back n accordingly, proper SQL query should be implemented on the adapter level since it involves different syntax for each DBMS.
-
Stephen Celis October 15th, 2010 @ 07:58 PM
I'm happy to fix the patch if there's interest in getting this into Rails.
@Elad, I'm not sure what you're saying. The Rails default for ActiveRecord::Base.first is to fetch one record from the database (with :limit => 1). As soon as you add a numeric argument, however, it fetches all, which is not what I would have expected. The only case I can think of where .first(n) would fetch all is ActiveRecord::Base.all.first(n), because .all returns an Array.
-
Piotr Sarnacki December 17th, 2010 @ 11:10 AM
I would add such functionality, anyone have anything against it?
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>