Module: OrderAsSpecified
- Defined in:
- lib/order_as_specified.rb,
lib/order_as_specified/error.rb,
lib/order_as_specified/version.rb
Overview
This module adds the ability to query an ActiveRecord class for results from the database in an arbitrary order, without having to store anything extra in the database. Simply extend it into your class and then you can use the order_as_specified class method.
Defined Under Namespace
Classes: Error
Constant Summary collapse
- VERSION =
"1.3"
Instance Method Summary collapse
-
#order_as_specified(hash) ⇒ ActiveRecord::Relation
The objects, ordered as specified.
Instance Method Details
#order_as_specified(hash) ⇒ ActiveRecord::Relation
Returns the objects, ordered as specified.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/order_as_specified.rb', line 12 def order_as_specified(hash) distinct_on = hash.delete(:distinct_on) params = extract_params(hash) table = connection.quote_table_name(params[:table]) attribute = connection.quote_column_name(params[:attribute]) # We have to explicitly quote for now because SQL sanitization for ORDER BY # queries isn't in less current versions of Rails. # See: https://github.com/rails/rails/pull/13008 db_connection = ActiveRecord::Base.connection conditions = params[:values].map do |value| raise OrderAsSpecified::Error, "Cannot order by `nil`" if value.nil? # Sanitize each value to reduce the risk of SQL injection. "#{table}.#{attribute}=#{db_connection.quote(value)}" end scope = order(conditions.map { |cond| "#{cond} DESC" }.join(", ")) if distinct_on scope = scope.select("DISTINCT ON (#{conditions.join(', ')}) #{table}.*") end scope end |