Module: ActiveRecordExtended::Utilities::OrderBy
- Included in:
- QueryMethods::Json::JsonChain, QueryMethods::Select::SelectHelper, QueryMethods::Unionize::UnionChain, QueryMethods::Window::DefineWindowChain
- Defined in:
- lib/active_record_extended/utilities/order_by.rb
Instance Method Summary collapse
- #inline_order_by(arel_node, ordering_args) ⇒ Object
-
#order_by_expression(order_by) ⇒ Object
Processes “ORDER BY” expressions for supported aggregate functions.
- #process_ordering_arguments!(ordering_args) ⇒ Object
- #scope_preprocess_order_args(ordering_args) ⇒ Object
-
#to_ordered_table_path(args) ⇒ Object
Turns a hash into a dot notation path.
Instance Method Details
#inline_order_by(arel_node, ordering_args) ⇒ Object
8 9 10 11 12 |
# File 'lib/active_record_extended/utilities/order_by.rb', line 8 def inline_order_by(arel_node, ordering_args) return arel_node unless scope_preprocess_order_args(ordering_args) Arel::Nodes::InfixOperation.new("ORDER BY", arel_node, ordering_args) end |
#order_by_expression(order_by) ⇒ Object
Processes “ORDER BY” expressions for supported aggregate functions
23 24 25 26 27 28 29 |
# File 'lib/active_record_extended/utilities/order_by.rb', line 23 def order_by_expression(order_by) return false unless order_by && order_by.presence.present? to_ordered_table_path(order_by) .tap { |order_args| process_ordering_arguments!(order_args) } .tap { |order_args| scope_preprocess_order_args(order_args) } end |
#process_ordering_arguments!(ordering_args) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/active_record_extended/utilities/order_by.rb', line 63 def process_ordering_arguments!(ordering_args) ordering_args.flatten! ordering_args.compact! ordering_args.map! do |arg| next to_arel_sql(arg) unless arg.is_a?(Hash) # ActiveRecord will reflect if an argument is a symbol arg.each_with_object({}) do |(field, dir), ordering_obj| # ActiveRecord will not reflect if the Hash keys are a `Arel::Nodes::SqlLiteral` klass ordering_obj[to_arel_sql(field)] = dir.to_s.downcase end end end |
#scope_preprocess_order_args(ordering_args) ⇒ Object
14 15 16 17 18 19 20 |
# File 'lib/active_record_extended/utilities/order_by.rb', line 14 def scope_preprocess_order_args(ordering_args) return false if ordering_args.blank? || !@scope.respond_to?(:preprocess_order_args, true) # Sanitation check / resolver (ActiveRecord::Relation#preprocess_order_args) @scope.send(:preprocess_order_args, ordering_args) ordering_args end |
#to_ordered_table_path(args) ⇒ Object
Turns a hash into a dot notation path.
Example:
-
Using pre-set directions:
- { products: { position: :asc, id: :desc } }
-
#=> [{ “products.position” => :asc, “products.id” => :desc }]
-
Using fallback directions:
- :position
-
#=> [=> :asc]
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/active_record_extended/utilities/order_by.rb', line 43 def to_ordered_table_path(args) flatten_safely(Array.wrap(args)) do |arg| next arg unless arg.is_a?(Hash) arg.each_with_object({}) do |(tbl_or_col, obj), new_hash| if obj.is_a?(Hash) obj.each_pair do |o_key, o_value| new_hash["#{tbl_or_col}.#{o_key}"] = o_value end elsif ::ActiveRecord::QueryMethods::VALID_DIRECTIONS.include?(obj) new_hash[tbl_or_col] = obj elsif obj.nil? new_hash[tbl_or_col.to_s] = :asc else new_hash["#{tbl_or_col}.#{obj}"] = :asc end end end end |