Module: ActiveRpc::Rpc::Concerns::Sortable

Extended by:
ActiveSupport::Concern
Included in:
QueryBuilder
Defined in:
lib/active_rpc/rpc/concerns/sortable.rb

Overview

The Sortable concern provides methods for applying sorting to ActiveRecord queries in gRPC controllers.

Examples:

def list_users
  process_request do
    base_query = User.all
    query = apply_sorting(base_query, request.message)
    # ...
  end
end

Instance Method Summary collapse

Instance Method Details

#apply_sorting(query, params) ⇒ Object

Apply sorting to a query



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/active_rpc/rpc/concerns/sortable.rb', line 19

def apply_sorting(query, params)
  return query unless params.respond_to?(:sort) && params.sort.present?

  begin
    # Parse the sort parameter
    field, direction = params.sort.split(' ')
    direction ||= 'asc'

    # Sanitize the direction
    direction = %w[asc desc].include?(direction.downcase) ? direction.downcase : 'asc'

    # Get query configuration
    query_config = get_query_config(query.model)
    sortable_attrs = query_config[:sortable] || []

    # Check if the field is sortable or if we have no defined sortable attributes
    if sortable_attrs.empty? || sortable_attrs.include?(field.to_sym) || sortable_attrs.include?(field.to_s)
      # Apply sorting
      query.order("#{field} #{direction}")
    else
      Rails.logger.error("Invalid sort field: #{field}")
      query
    end
  rescue => e
    Rails.logger.error("Error applying sorting: #{e.message}")
    # Return original query if sorting fails
    query
  end
end

#get_query_config(model_class) ⇒ Object

Get query configuration for a model



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/active_rpc/rpc/concerns/sortable.rb', line 50

def get_query_config(model_class)
  if model_class.respond_to?(:active_rpc_config) && model_class.active_rpc_config
    resource = model_class.active_rpc_config[:resource].to_s.underscore
    query_config_method = "#{resource}_query_config"

    if model_class.respond_to?(query_config_method)
      return model_class.send(query_config_method)
    end
  end

  # Default configuration if none is defined
  {
    searchable: model_class.column_names,
    filterable: model_class.column_names,
    sortable: model_class.column_names,
    includable: model_class.reflect_on_all_associations.map(&:name)
  }
end