Hi guys,
I don't think that the changes made to the behavior of #all in 4.0 are a very good idea.
I can see that you no longer need to call all in as many cases as you did before - that's fine, just don't call it if you don't want it. But that doesn't mean you never need it or that people who do need it should not have it available.
1. Yes you can use to_a in many cases, but it behaves differently - for example if you have an association, to_a will return the cached target if the association has already been loaded. You absolutely need a way to run an actual query when you want the latest results. to_a cannot be relied upon to do this in all cases.
Note lack of a second query:
irb(main):006:0> p = Project.first Project Load (0.2ms) SELECT "projects".* FROM "projects" ORDER BY "projects"."id" ASC LIMIT 1 => #<Project id: 1, created_at: "2013-02-27 09:38:49", updated_at: "2013-02-27 09:38:49"> irb(main):007:0> p.tasks.to_a Task Load (0.2ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."project_id" = ? [["project_id", 1]] => [#<Task id: 1, project_id: 1, created_at: "2013-02-27 09:38:52", updated_at: "2013-02-27 09:38:52">, #<Task id: 2, project_id: 1, created_at: "2013-02-27 09:38:53", updated_at: "2013-02-27 09:38:53">] irb(main):008:0> p.tasks.to_a => [#<Task id: 1, project_id: 1, created_at: "2013-02-27 09:38:52", updated_at: "2013-02-27 09:38:52">, #<Task id: 2, project_id: 1, created_at: "2013-02-27 09:38:53", updated_at: "2013-02-27 09:38:53">] irb(main):010:0> p.tasks.all DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (e.g. `Post.where(published: true).load`). If you want to get an array of records from a relation, you can call #to_a (e.g. `Post.where(published: true).to_a`). (called from irb_binding at (irb):10) => [#<Task id: 1, project_id: 1, created_at: "2013-02-27 09:38:52", updated_at: "2013-02-27 09:38:52">, #<Task id: 2, project_id: 1, created_at: "2013-02-27 09:38:53", updated_at: "2013-02-27 09:38:53">] irb(main):011:0> p.tasks.all DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (e.g. `Post.where(published: true).load`). If you want to get an array of records from a relation, you can call #to_a (e.g. `Post.where(published: true).to_a`). (called from irb_binding at (irb):11) => [#<Task id: 1, project_id: 1, created_at: "2013-02-27 09:38:52", updated_at: "2013-02-27 09:38:52">, #<Task id: 2, project_id: 1, created_at: "2013-02-27 09:38:53", updated_at: "2013-02-27 09:38:53">]
2. It's very important that queries run at the point you think they do in any application that uses locks or concurrency. Again, if you don't use locks or concurrency, fine - don't call the query methods. But many people do and they need to be able to run the queries to make this work.
3. It's not true that you no longer need to care whether you have an array or a relation. For example, methods like sum with a block need arrays, as the deprecation makes clear:
irb(main):009:0> p.tasks.sum(&:id) DEPRECATION WARNING: Calling #sum with a block is deprecated and will be removed in Rails 4.1. If you want to perform sum calculation over the array of elements, use `to_a.sum(&block)`. (called from irb_binding at (irb):9) Task Load (0.1ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."project_id" = ? [["project_id", 1]] => 3
4. It's true that making all basically useless means you can now call all on a model class itself and get a relation and then you can merge that or whatever, which was one of the other examples in the changelog. But you could do that already - using scoped. It is not necessary to break #all's behavior to get this functionality.
Have I misunderstood the change?
If not, can we please put back the query method? Running queries is a pretty core responsibility of ActiveRecord.
Thanks, Will