class ApiPresenter::Base
Attributes
Public Class Methods
@example
@presenter = PostPresenter.call( current_user: current_user, relation: relation, params: params )
@param (see initialize)
@return [ApiPresenter::Base]
# File lib/api_presenter/base.rb, line 17 def self.call(**kwargs) new(kwargs).call end
@param current_user
[User] Optional. current_user
context. @param relation [ActiveRecord::Relation, Array] Relation or array-wrapped record(s) to present @param params [Hash] Controller params @option params [Boolean] :count Optional. If true, return count only. @option params [String, Array] :include Optional. Associated resources to include. @option params [Boolean] :policies Optional. If true, resolve polciies for relation.
# File lib/api_presenter/base.rb, line 28 def initialize(current_user: nil, relation:, params: {}) @current_user = current_user @relation = relation @params = params end
Public Instance Methods
Hash map that defines the sources for included collection names
@example
def associations_map { categories: { associations: { sub_category: :category } }, sub_categories: { associations: :sub_category }, users: { associations: [:creator, :publisher] } } end
@abstract
@return [Hash]
# File lib/api_presenter/base.rb, line 128 def associations_map {} end
@return [ApiPresenter::Base]
# File lib/api_presenter/base.rb, line 36 def call return self if count_only? initialize_resolvers call_resolvers self end
Primary collection, empty if count requested
@return [ActiveRecord::Relation, Array<ActiveRecord::Base>]
# File lib/api_presenter/base.rb, line 47 def collection count_only? ? [] : relation end
Class names of included collections
@example
[:categories, :sub_categories, :users]
@return [Array<Symbol>]
# File lib/api_presenter/base.rb, line 82 def included_collection_names @included_collection_names ||= Parsers::ParseIncludeParams.call(params[ApiPresenter.configuration.include_param]) end
Map of included collection names and loaded record
@example
{ categories: [#<Category id:1>], sub_categories: [#<SubCategory id:1>], users: [#<User id:1>, #<User id:2] }
@return [Hash]
# File lib/api_presenter/base.rb, line 97 def included_collections @included_collections_resolver ? @included_collections_resolver.resolved_collections : {} end
Policies for the primary collection
@example
[ { post_id: 1, update: true, destroy: true }, { post_id: 2, update: false, destroy: false } ]
@return [<Array<Hash>]
# File lib/api_presenter/base.rb, line 71 def policies @policies_resolver ? @policies_resolver.resolved_policies : {} end
Policy associations to preload to optimize policy resolution
@example Single
def policy_associations :user_profile end
@example Multiple
def policy_associations [:user_profile, :company] end
@abstract
@return [Symbol, Array<Symbol>]
# File lib/api_presenter/base.rb, line 168 def policy_associations [] end
Policy methods to resolve for the primary relation
@example Single
def policy_methods :update end
@example Multiple
def policy_methods [:update, :destroy] end
@abstract
@return [Symbol, Array<Symbol>]
# File lib/api_presenter/base.rb, line 148 def policy_methods [] end
Preload additional records with the relation
@note Called by resolvers, but can also be called if additional data is required that does
not need to be loaded as an included collection, and for some reason cannot be chained onto the original relation.
@param associations [Symbol, Array<Symbol>]
# File lib/api_presenter/base.rb, line 109 def preload(associations) @relation = @relation.preload(associations) end
Count of primary collection
@note Delegate to Kaminari's `total_count` property, or regular count if not a paginated relation
@return [Integer]
# File lib/api_presenter/base.rb, line 57 def total_count relation.respond_to?(:total_count) ? relation.total_count : relation.count end
Private Instance Methods
# File lib/api_presenter/base.rb, line 191 def call_resolvers @policies_resolver.call if @policies_resolver @included_collections_resolver.call if @included_collections_resolver end
# File lib/api_presenter/base.rb, line 174 def count_only? @count_only ||= !!params[ApiPresenter.configuration.count_param] end
# File lib/api_presenter/base.rb, line 186 def initialize_resolvers @policies_resolver = Resolvers::PoliciesResolver.new(self) if resolve_policies? @included_collections_resolver = Resolvers::IncludedCollectionsResolver.new(self) if resolve_included_collctions? end
# File lib/api_presenter/base.rb, line 182 def resolve_included_collctions? included_collection_names.any? end
# File lib/api_presenter/base.rb, line 178 def resolve_policies? @resolve_policies ||= current_user && !!params[ApiPresenter.configuration.policies_param] end