I agree very much with James and would add that if iteration was done in 
this manner it would not improve performance since the additional queries 
add round-trip time (latency, db query setup, etc) which typically exceeds 
time spent returning results, especially in multi-tier environments. In my 
environment with 270k user rows, calling User.offset(x).first with five 
ID's varying by 50000 was 23% slower than calling User.all. I imagine this 
would be far worse for larger iteration strides.

As far as idiomatics are concerned, `all` returning an eagerly-loaded array 
is more idiomatic to me than `all` returning a proxy that quacks like an 
array but lazily-loads items. The current implementation of `all` makes 
working with a cohesive or related set of objects trivial, especially in 
the face of database contention. What happens if rows change while my 
application is making a bunch of queries for individual records? I would 
either risk getting inconsistent data or I'd have to create a locking 
scheme.

These all seem like high prices to pay for a debatable idiomatic change.


On Friday, July 19, 2013 7:40:27 AM UTC-4, James Coleman wrote:
>
> The whole point of the `all` method is that it actually fires the query on 
> the current relation. So 1.) a change like this could potentially break a 
> lot of existing code and 2.) it would defeat the point of the method. So I 
> strongly believe that it shouldn't change. If you want the limit/offset 
> query, use those methods. That's why they're there.
>
>
> On Fri, Jul 19, 2013 at 12:14 AM, Michael Swan <[email protected]<javascript:>
> > wrote:
>
>> Your example would involve three queries, each only allocating memory and 
>> transferring content from the DBMS for 1 result, instead of every record in 
>> the table.
>>
>> In the present:
>> User.all[5] # SELECT "users".* FROM "users" -> 420,000 results
>>
>> My suggestion:
>> User.all[5] # SELECT "users".* FROM "users" LIMIT 1 OFFSET 5 -> 1 result
>>
>> If I understand right, every User is pulled from the database, an array 
>> is created with every single possible instance of a User, and then you 
>> select a specific value from that array. I am thinking about this in the 
>> context of any query. If you want the nth result from that query, it would 
>> be nice to have an idiomatic shorthand for that, instead of 
>> ".offset(n).first".
>>
>> It appears that even if you are iterating over the elements in a query in 
>> such a way, my suggestion would improve performance. This has nothing to do 
>> with any of the other functions that are delegated to Array. This is for an 
>> ActiveRecord query that one is looking for the nth element within those 
>> query results.
>>
>> No one in their right mind would use the delegated '[]' function on a 
>> query that could have thousands of results. But they would call the '[]' 
>> function that I am suggesting.
>>
>> On Friday, July 12, 2013 1:28:18 PM UTC-4, Olly Smith wrote:
>>>
>>> What do you expect to happen if the code looks like this:
>>>
>>> User.all[5]
>>> User.all[6]
>>> User.all[7]
>>>
>>> Should ActiveRecord make three separate queries? How about if the code 
>>> iterates from index 100 to 200?
>>>
>>> Imho, it's totally acceptable to sacrifice 'idiomatic' ruby in this case 
>>> in favour of fewer accidental gotchas.
>>>
>>> Olly
>>> On 12 Jul 2013 17:29, "Michael Swan" <[email protected]> wrote:
>>>
>>>> I am going to make this quick. Try something like: User.all[5]
>>>> Rails presently runs the following query in Postgres: SELECT "users".* 
>>>> FROM "users"
>>>> And then gets the 6th element from the array of results.
>>>>
>>>> In reality, User.all[5] should be equivalent to: 
>>>> User.limit(1).offset(5).first
>>>> in all circumstances that this addition to the query can be performed.
>>>> This means that someone looking for the nth User, for example, can 
>>>> simply use the brackets as is idiomatic in Ruby, to perform the query 
>>>> which 
>>>> is truly desired by the user.
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "Ruby on Rails: Core" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to rubyonrails-co...@**googlegroups.com.
>>>> To post to this group, send email to rubyonra...@googlegroups.**com.
>>>> Visit this group at 
>>>> http://groups.google.com/**group/rubyonrails-core<http://groups.google.com/group/rubyonrails-core>
>>>> .
>>>> For more options, visit 
>>>> https://groups.google.com/**groups/opt_out<https://groups.google.com/groups/opt_out>
>>>> .
>>>>  
>>>>  
>>>>
>>>  -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Ruby on Rails: Core" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] <javascript:>.
>> To post to this group, send email to 
>> [email protected]<javascript:>
>> .
>> Visit this group at http://groups.google.com/group/rubyonrails-core.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>  
>>  
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to