module RESTFramework::BaseModelControllerMixin
This module provides the core functionality for controllers based on models.
Public Class Methods
# File lib/rest_framework/controller_mixins/models.rb, line 9 def self.included(base) if base.is_a? Class RESTFramework::BaseControllerMixin.included(base) # Add class attributes (with defaults) unless they already exist. { # Core attributes related to models. model: nil, recordset: nil, # Attributes for configuring record fields. fields: nil, action_fields: nil, # Attributes for finding records. find_by_fields: nil, find_by_query_param: 'find_by', # Attributes for create/update parameters. allowed_parameters: nil, allowed_action_parameters: nil, # Attributes for the default native serializer. native_serializer_config: nil, native_serializer_singular_config: nil, native_serializer_plural_config: nil, # Attributes for default model filtering (and ordering). filterset_fields: nil, ordering_fields: nil, ordering_query_param: 'ordering', ordering_no_reorder: false, search_fields: nil, search_query_param: 'search', search_ilike: false, # Other misc attributes. create_from_recordset: true, # Option for `recordset.create` vs `Model.create` behavior. filter_recordset_before_find: true, # Option to control if filtering is done before find. }.each do |a, default| unless base.respond_to?(a) base.class_attribute(a) # Set default manually so we can still support Rails 4. Maybe later we can use the default # parameter on `class_attribute`. base.send(:"#{a}=", default) end end end end
Protected Instance Methods
# File lib/rest_framework/controller_mixins/models.rb, line 62 def _get_specific_action_config(action_config_key, generic_config_key) action_config = self.class.send(action_config_key) || {} action = self.action_name&.to_sym # Index action should use :list serializer if :index is not provided. action = :list if action == :index && !action_config.key?(:index) return (action_config[action] if action) || self.class.send(generic_config_key) end
Get a list of parameters allowed for the current action.
# File lib/rest_framework/controller_mixins/models.rb, line 102 def get_allowed_parameters return _get_specific_action_config(:allowed_action_parameters, :allowed_parameters)&.map(&:to_s) end
Filter the request body for keys in current action's allowed_parameters/fields config.
# File lib/rest_framework/controller_mixins/models.rb, line 119 def get_body_params return @_get_body_params ||= begin fields = self.get_allowed_parameters || self.get_fields # Filter the request body. body_params = request.request_parameters.select { |p| fields.include?(p) } # Add query params in place of missing body params, if configured. if self.class.accept_generic_params_as_body_params (fields - body_params.keys).each do |k| if (value = params[k]) body_params[k] = value end end end # Filter primary key if configured. if self.class.filter_pk_from_request_body body_params.delete(self.get_model&.primary_key) end # Filter fields in exclude_body_fields. (self.class.exclude_body_fields || []).each { |f| body_params.delete(f.to_s) } body_params end end
Get a list of fields for the current action.
# File lib/rest_framework/controller_mixins/models.rb, line 73 def get_fields return ( _get_specific_action_config(:action_fields, :fields)&.map(&:to_s) || self.get_model&.column_names || [] ) end
Helper to get filtering backends, defaulting to using `ModelFilter` and `ModelOrderingFilter`.
# File lib/rest_framework/controller_mixins/models.rb, line 112 def get_filter_backends return self.class.filter_backends || [ RESTFramework::ModelFilter, RESTFramework::ModelOrderingFilter ] end
Get a list of find_by fields for the current action.
# File lib/rest_framework/controller_mixins/models.rb, line 87 def get_filterset_fields return self.class.filterset_fields&.map(&:to_s) || self.get_fields end
Get a list of find_by fields for the current action.
# File lib/rest_framework/controller_mixins/models.rb, line 82 def get_find_by_fields return self.class.find_by_fields&.map(&:to_s) || self.get_fields end
Get the model for this controller.
# File lib/rest_framework/controller_mixins/models.rb, line 150 def get_model(from_get_recordset: false) return @model if instance_variable_defined?(:@model) && @model return (@model = self.class.model) if self.class.model # Delegate to the recordset's model, if it's defined. unless from_get_recordset # prevent infinite recursion if (recordset = self.get_recordset) return @model = recordset.klass end end # Try to determine model from controller name. begin return (@model = self.class.name.demodulize.match(/(.*)Controller/)[1].singularize.constantize) rescue NameError end return nil end
Get a list of ordering fields for the current action.
# File lib/rest_framework/controller_mixins/models.rb, line 92 def get_ordering_fields return self.class.ordering_fields&.map(&:to_s) || self.get_fields end
Get a single record by primary key or another column, if allowed.
# File lib/rest_framework/controller_mixins/models.rb, line 184 def get_record recordset = self.get_recordset find_by_fields = self.get_find_by_fields find_by_key = self.get_model.primary_key # Find by another column if it's permitted. if find_by_query_param && params[find_by_query_param].in?(find_by_fields) find_by_key = params[find_by_query_param] end # Filter recordset, if configured. if self.filter_recordset_before_find recordset = self.get_filtered_data(recordset) end # Return the record. if find_by_value = params[:id] # Route key is always :id by Rails convention. return self.get_recordset.find_by!(find_by_key => find_by_value) end return nil end
Get the set of records this controller has access to.
# File lib/rest_framework/controller_mixins/models.rb, line 171 def get_recordset return @recordset if instance_variable_defined?(:@recordset) && @recordset return (@recordset = self.class.recordset) if self.class.recordset # If there is a model, return that model's default scope (all records by default). if (model = self.get_model(from_get_recordset: true)) return @recordset = model.all end return nil end
Get a list of search fields for the current action.
# File lib/rest_framework/controller_mixins/models.rb, line 97 def get_search_fields return self.class.search_fields&.map(&:to_s) || self.get_fields end
Helper to get the configured serializer class, or `NativeSerializer` as a default.
# File lib/rest_framework/controller_mixins/models.rb, line 107 def get_serializer_class return self.class.serializer_class || RESTFramework::NativeSerializer end