Module: Insights::API::Common::ApplicationControllerMixins::Parameters

Defined in:
lib/insights/api/common/application_controller_mixins/parameters.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(other) ⇒ Object



6
7
8
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 6

def self.included(other)
  other.include(OpenapiEnabled)
end

Instance Method Details

#all_attributes_for_indexObject



86
87
88
89
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 86

def all_attributes_for_index
  check_if_openapi_enabled
  api_doc_definition.all_attributes + [subcollection_foreign_key_using_through_relation]
end

#check_if_openapi_enabledObject

Raises:

  • (ArgumentError)


139
140
141
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 139

def check_if_openapi_enabled
  raise ArgumentError, "Openapi not enabled" unless self.class.openapi_enabled
end

#extra_attributes_for_filteringObject



100
101
102
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 100

def extra_attributes_for_filtering
  {}
end

#filteredObject



91
92
93
94
95
96
97
98
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 91

def filtered
  check_if_openapi_enabled
  association_attribute_properties =
    Insights::API::Common::Filter.association_attribute_properties(api_doc_definitions, safe_params_for_list[:filter])
  extra_attribute_properties = extra_attributes_for_filtering.merge(association_attribute_properties)

  Insights::API::Common::Filter.new(model, safe_params_for_list[:filter], api_doc_definition, extra_attribute_properties).apply
end

#pagination_limitObject



104
105
106
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 104

def pagination_limit
  safe_params_for_list[:limit]
end

#pagination_offsetObject



108
109
110
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 108

def pagination_offset
  safe_params_for_list[:offset]
end

#params_for_createObject



10
11
12
13
14
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 10

def params_for_create
  check_if_openapi_enabled
  # We already validate this with OpenAPI validator, that validates every request, so we shouldn't do it again here.
  body_params.permit!
end

#params_for_listObject



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 46

def params_for_list
  check_if_openapi_enabled
  safe_params = safe_params_for_list.slice(*all_attributes_for_index)
  if safe_params[subcollection_foreign_key_using_through_relation]
    # If this is a through relation, we need to replace the :foreign_key by the foreign key with right table
    # information. So e.g. :container_images with :tags subcollection will have {:container_image_id => ID} and we need
    # to replace it with {:container_images_tags => {:container_image_id => ID}}, where :container_images_tags is the
    # name of the mapping table.
    safe_params[through_relation_klass.table_name.to_sym] = {
      subcollection_foreign_key_using_through_relation => safe_params.delete(subcollection_foreign_key_using_through_relation)
    }
  end

  safe_params
end

#params_for_polymorphic_subcollectionObject



34
35
36
37
38
39
40
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 34

def params_for_polymorphic_subcollection
  return {} unless subcollection?
  return {} unless reflection = primary_collection_model&.reflect_on_association(request_path_parts["subcollection_name"])
  return {} unless as = reflection.options[:as]

  {"#{as}_type" => primary_collection_model.name, "#{as}_id" => request_path_parts["primary_collection_id"]}
end

#params_for_updateObject



116
117
118
119
120
121
122
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 116

def params_for_update
  check_if_openapi_enabled
  # We already validate this with OpenAPI validator, here only to satisfy the strong parameters check
  attr_list = *api_doc_definition.all_attributes - api_doc_definition.read_only_attributes
  strong_params_hash = sanctified_permit_param(api_doc_definition, attr_list)
  body_params.permit(strong_params_hash)
end

#permitted_paramsObject



25
26
27
28
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 25

def permitted_params
  check_if_openapi_enabled
  api_doc_definition.all_attributes + [:limit, :offset, :sort_by] + [subcollection_foreign_key]
end

#primary_collection_modelObject



42
43
44
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 42

def primary_collection_model
  @primary_collection_model ||= request_path_parts["primary_collection_name"].singularize.classify.safe_constantize
end

#query_sort_byObject



112
113
114
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 112

def query_sort_by
  safe_params_for_list[:sort_by]
end

#safe_params_for_listObject



16
17
18
19
20
21
22
23
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 16

def safe_params_for_list
  check_if_openapi_enabled
  # :limit & :offset can be passed in for pagination purposes, but shouldn't show up as params for filtering purposes
  @safe_params_for_list ||= begin
    sort_by_default = (params[:sort_by].kind_of?(String) || params[:sort_by].kind_of?(Array)) ? [] : {}
    params.merge(params_for_polymorphic_subcollection).permit(*permitted_params, :filter => {}, :sort_by => sort_by_default)
  end
end

#sanctified_permit_param(api_doc_definition, attributes) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 124

def sanctified_permit_param(api_doc_definition, attributes)
  api_doc_definition['properties'].each_with_object([]) do |(k, v), memo|
    # only add to the permit hash if we're actually trying to update it.
    next unless attributes.any? { |attr| attr.include?(k) }

    memo << if v['type'] == 'array'
              { k => [] }
            elsif v['type'] == 'object'
              { k => {} }
            else
              k
            end
  end
end

#subcollection_foreign_keyObject



30
31
32
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 30

def subcollection_foreign_key
  "#{request_path_parts["primary_collection_name"].singularize}_id"
end

#subcollection_foreign_key_using_through_relationObject



80
81
82
83
84
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 80

def subcollection_foreign_key_using_through_relation
  return unless through_relation_klass

  subcollection_foreign_key
end

#through_relation_klassObject



62
63
64
65
66
67
68
69
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 62

def through_relation_klass
  check_if_openapi_enabled
  return unless subcollection?
  return unless reflection = primary_collection_model&.reflect_on_association(request_path_parts["subcollection_name"])
  return unless through = reflection.options[:through]

  primary_collection_model&.reflect_on_association(through).klass
end

#through_relation_nameObject



71
72
73
74
75
76
77
78
# File 'lib/insights/api/common/application_controller_mixins/parameters.rb', line 71

def through_relation_name
  check_if_openapi_enabled
  # Through relation name taken from the subcollection model side, so we can use this for table join.
  return unless through_relation_klass
  return unless through_relation_association = model.reflect_on_all_associations.detect { |x| !x.polymorphic? && x.klass == through_relation_klass }

  through_relation_association.name
end