ActiveRecord chained order calls composed

When chaining calls to order on an ActiveRecord association, the result is a composition of the two order calls. I believe this breaks the principle of least surprise, since calling sort/order on a collection never behaves like this anywhere else (for example with Array#sort). Any subsequent calls to order should re-order the collection in the way you specify.

I can’t imagine any situations where you would chain calls to order and want/expect this behaviour, but I can think of many situations where it can lead to unexpected results (for example when using default_scope for ordering).

I propose that reorder be renamed to order, and order be renamed to append_order or something similar.

Thoughts?

We could debate all day what the “correct” way to do it is, but the reality is that (and this has been discussed before) that this would be a tremendously breaking API change, and therefore shouldn’t be done regardless.

I will add my 2 cents though on the idea: I don’t think that comparing relations to arrays is a valid comparison. In the array you’re working with static, mutable, data, but with a relation you are, by definition, working with something that is composable (under relational set theory). So the fact that the result is a composition is actually the correct thing for this type.

+1

I don’t think of ActiveRecord as an API for manipulating collections of data but instead an API for composing queries (and mapping data, etc.). I don’t know what’s “correct”, but it feels intuitive to me that order calls would be composed consistently with where calls.

Relational algebra deals with sets, and sets are collections. Standard relational algebra doesn’t define an order by operator, but if you want define an order between the elements in the set, you’re getting towards something which behaves quite a lot like an array.

James, I see your point about api-breaking changes. How about updating the guide to notify people of this behaviour in case they do not expect it, and let them know that the reorder method exists too?

It’s true that relations as sets that to feel a whole lot like arrays, but the fact that query conditions are composable (and no one is arguing that they shouldn’t be) implies that other operations should also be composable. To have conditions be composable and orderings not would be an impedance mismatch that would violate the POLS actually.

As far as the default_scope issues, I personally believe that default orderings on either default_scope or associations should be considered harmful and are generally a hack fix for view sorting that violates separation of concerns.

If you want a specific ordering and you’re using a pre-made relation (like an association), perhaps you should be using reorder.

I’m totally in favor of clarifying docs however.