class Para::Search::Distinct
Attributes
Public Class Methods
Source
# File lib/para/search/distinct.rb, line 13 def initialize(search) @search = search @sort_index ||= 0 end
Public Instance Methods
Source
# File lib/para/search/distinct.rb, line 18 def result selects = build_selects search.result.select(selects).distinct end
Private Instance Methods
Source
# File lib/para/search/distinct.rb, line 78 def build_alias(sql, index) Arel::Nodes::InfixOperation.new( 'AS', format_string(sql), Arel::Nodes::SqlLiteral.new(index) ).to_sql end
Source
# File lib/para/search/distinct.rb, line 25 def build_selects ([table_wildcard_select] + sort_selects).join(', ') end
Source
# File lib/para/search/distinct.rb, line 86 def format_string(sql) sql_lower(sql_unaccent(sql_stringify(sql))) end
Source
# File lib/para/search/distinct.rb, line 70 def next_sort_index ['sort', @sort_index += 1].join('_') end
Source
# File lib/para/search/distinct.rb, line 50 def process_attribute(sort) sort_index = next_sort_index sql = [sort.attr.relation.name, sort.attr.name].join('.') replace_sort(sort, sort_index) build_alias(sql, sort_index) end
Source
# File lib/para/search/distinct.rb, line 62 def process_sql_literal(sort) sort_index = next_sort_index sql = sort.attr.to_s replace_sort(sort, sort_index) build_alias(sql, sort_index) end
When given an SQL literal, we store the sql expression in a named SELECT variable, and replace the expression by its variable name inside of the ransack sort instance
Source
# File lib/para/search/distinct.rb, line 74 def replace_sort(sort, sort_index) sort.instance_variable_set(:@attr, Arel::Nodes::SqlLiteral.new(sort_index)) end
Source
# File lib/para/search/distinct.rb, line 33 def sort_selects return [] unless search search.sorts.map do |sort| case sort.attr when Arel::Attributes::Attribute then process_attribute(sort) when Arel::Nodes::SqlLiteral then process_sql_literal(sort) # # Explicitly raise here to avoid the system to swallow sorting errors, # since any unsupported class must have been explicitly used by the # developer, and debugging it would be hard without an exception # else raise "Unsupported sort attribute class : #{ sort.attr.class.name }" end end end
Source
# File lib/para/search/distinct.rb, line 90 def sql_lower(sql) Arel::Nodes::NamedFunction.new('LOWER', [sql]) end
Source
# File lib/para/search/distinct.rb, line 98 def sql_stringify(sql) Arel::Nodes::NamedFunction.new( 'CAST', [ Arel::Nodes::InfixOperation.new( 'AS', Arel::Nodes::SqlLiteral.new(sql), Arel::Nodes::SqlLiteral.new('text') ) ] ) end
Source
# File lib/para/search/distinct.rb, line 94 def sql_unaccent(sql) Arel::Nodes::NamedFunction.new('UNACCENT', [sql]) end
Source
# File lib/para/search/distinct.rb, line 29 def table_wildcard_select [search.klass.table_name, '*'].join('.') end