From d6a38d2c430befd30ff8e97f352ae3dbed81136e Mon Sep 17 00:00:00 2001 From: Rachael Wright-Munn Date: Sun, 15 Aug 2021 19:16:13 +0000 Subject: [PATCH] Improve Documentation around the options that can be passed to order. Co-authored-by: Petrik de Heus Co-authored-by: Jonathan Hefner --- .../active_record/relation/query_methods.rb | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index ee6d366c907..ee06480364b 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -354,17 +354,37 @@ module ActiveRecord self end - # Allows to specify an order attribute: + # Applies an ORDER BY clause to a query. + # + # #order accepts arguments in one of several formats. + # + # === symbols + # + # The symbol represents the name of the column you want to order the results by. # # User.order(:name) # # SELECT "users".* FROM "users" ORDER BY "users"."name" ASC # + # By default, the order is ascending. If you want descending order, you can + # map the column name symbol to +:desc+. + # # User.order(email: :desc) # # SELECT "users".* FROM "users" ORDER BY "users"."email" DESC # + # Multiple columns can be passed this way, and they will be applied in the order specified. + # # User.order(:name, email: :desc) # # SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC # + # === strings + # + # Strings are passed directly to the database, allowing you to specify + # simple SQL expressions. + # + # This could be a source of SQL injection, so only strings composed of plain + # column names and simple function(column_name) expressions + # with optional +ASC+/+DESC+ modifiers are allowed. + # # User.order('name') # # SELECT "users".* FROM "users" ORDER BY name # @@ -373,6 +393,19 @@ module ActiveRecord # # User.order('name DESC, email') # # SELECT "users".* FROM "users" ORDER BY name DESC, email + # + # === Arel + # + # If you need to pass in complicated expressions that you have verified + # are safe for the DB, you can use Arel. + # + # User.order(Arel.sql('end_date - start_date')) + # # SELECT "users".* FROM "users" ORDER BY end_date - start_date + # + # Custom query syntax, like JSON columns for Postgres, is supported in this way. + # + # User.order(Arel.sql("payload->>'kind'")) + # # SELECT "users".* FROM "users" ORDER BY payload->>'kind' def order(*args) check_if_method_has_arguments!(__callee__, args) do sanitize_order_arguments(args)