class Sortiri::Generators::OrderByGenerator

Attributes

columns_hash[R]
foreign_columns[R]
sortable_columns[R]
whitelisted_columns[R]

Public Class Methods

new(sortable_columns:, whitelisted_columns:) click to toggle source
# File lib/sortiri/generators/order_by_generator.rb, line 8
def initialize(sortable_columns:, whitelisted_columns:)
  @sortable_columns = sortable_columns # array of Sortiri::ActiveRecord::Column
  @whitelisted_columns = whitelisted_columns # array of Sortiri::Column
  @columns_hash = map_columns_and_active_record_columns
  @foreign_columns = select_unique_foreign_columns
end

Public Instance Methods

sort(model, reorder: false) click to toggle source
# File lib/sortiri/generators/order_by_generator.rb, line 15
def sort(model, reorder: false)
  query = if reorder
            model.reorder(generate_order_by_clauses)
          else
            model.order(generate_order_by_clauses)
          end
  query = query.joins(generate_joins(model)) if needs_join?
  query
end

Private Instance Methods

concatenate_column_and_direction(column_hash) click to toggle source
# File lib/sortiri/generators/order_by_generator.rb, line 50
def concatenate_column_and_direction(column_hash)
  Arel.sql("#{column_hash[:active_record_column].name_with_table_name} #{column_hash[:column].direction_sql}")
end
generate_joins(model) click to toggle source
# File lib/sortiri/generators/order_by_generator.rb, line 37
def generate_joins(model)
  source_arel_table = model.arel_table

  foreign_columns.map do |hash|
    active_record_column = hash[:active_record_column]
    target_arel_table = Arel::Table.new(active_record_column.table_name)

    # TODO: find a way to get primary key from target_arel_table
    source_arel_table.join(target_arel_table, Arel::Nodes::OuterJoin).
      on(source_arel_table[active_record_column.foreign_key.to_sym].eq(target_arel_table[:id]))
  end.map(&:join_sources)
end
generate_order_by_clauses() click to toggle source
# File lib/sortiri/generators/order_by_generator.rb, line 31
def generate_order_by_clauses
  columns_hash.map do |column_hash|
    concatenate_column_and_direction(column_hash)
  end.join(',')
end
map_columns_and_active_record_columns() click to toggle source
# File lib/sortiri/generators/order_by_generator.rb, line 54
def map_columns_and_active_record_columns
  whitelisted_columns.map do |column|
    sortable_column = sortable_columns.detect { |c| c.matches_with?(column) }

    { active_record_column: sortable_column, column: column }
  end
end
needs_join?() click to toggle source
# File lib/sortiri/generators/order_by_generator.rb, line 27
def needs_join?
  foreign_columns.present?
end
select_unique_foreign_columns() click to toggle source
# File lib/sortiri/generators/order_by_generator.rb, line 62
def select_unique_foreign_columns
  columns_hash.select { |c| c[:active_record_column].is_a?(Sortiri::ActiveRecord::ForeignColumn) }.
    uniq { |c| c[:active_record_column].association_name }
end