Sha256: 8ce6180bc4c75f800ac55adfd8e92b76bf72d6de9b25e21b9738e9db5bf32ef3
Contents?: true
Size: 1.88 KB
Versions: 2
Compression:
Stored size: 1.88 KB
Contents
require "order_as_specified/version" require "order_as_specified/error" # 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. module OrderAsSpecified # @param hash [Hash] the ActiveRecord arguments hash # @return [ActiveRecord::Relation] the objects, ordered as specified def order_as_specified(hash) distinct_on = hash.delete(:distinct_on) params = extract_params(hash) table = params[:table] attribute = 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 conditions = params[:values].map do |value| raise OrderAsSpecified::Error, "Cannot order by `nil`" if value.nil? "#{table}.#{attribute}='#{value}'" end scope = order(conditions.map { |cond| "#{cond} DESC" }.join(", ")) if distinct_on scope = scope.select("DISTINCT ON (#{conditions.join(', ')}) #{table}.*") end scope end private # Recursively search through the hash to find the last elements, which # indicate the name of the table we want to condition on, the attribute name, # and the attribute values for ordering by. # @param table [String/Symbol] the name of the table, default: the class table # @param hash [Hash] the ActiveRecord-style arguments, such as: # { other_objects: { id: [1, 5, 3] } } def extract_params(table = table_name, hash) raise "Could not parse params" unless hash.size == 1 key, val = hash.first if val.is_a? Hash extract_params(key, hash[key]) else { table: table, attribute: key, values: val } end end end
Version data entries
2 entries across 2 versions & 1 rubygems
Version | Path |
---|---|
order_as_specified-1.1 | lib/order_as_specified.rb |
order_as_specified-1.0 | lib/order_as_specified.rb |