module Graphiti module Links extend ActiveSupport::Concern DEFAULT_ACTIONS = [:index, :show, :create, :update, :destroy].freeze module Overrides def endpoint if endpoint = super endpoint else self.endpoint = infer_endpoint end end end included do class_attribute :endpoint, :base_url, :endpoint_namespace, :secondary_endpoints, :autolink, :validate_endpoints self.secondary_endpoints = [] self.autolink = true self.validate_endpoints = true class << self prepend Overrides end end class_methods do def infer_endpoint return unless name path = "/#{name.gsub('Resource', '').pluralize.underscore}".to_sym { path: path, full_path: full_path_for(path), url: url_for(path), actions: DEFAULT_ACTIONS.dup } end def primary_endpoint(path, actions = DEFAULT_ACTIONS.dup) path = path.to_sym self.endpoint = { path: path, full_path: full_path_for(path), url: url_for(path), actions: actions } end # NB: avoid << b/c class_attribute def secondary_endpoint(path, actions = DEFAULT_ACTIONS.dup) path = path.to_sym self.secondary_endpoints += [{ path: path, full_path: full_path_for(path), url: url_for(path), actions: actions }] end def endpoints ([endpoint] + secondary_endpoints).compact end def allow_request?(path, params, action) path = path.split('.')[0] endpoints.any? do |e| has_id = params[:id] || params[:data].try(:[], :id) if [:update, :show, :destroy].include?(context_namespace) && has_id path = path.split('/') path.pop path = path.join('/') end e[:full_path].to_s == path && e[:actions].include?(context_namespace) end end private def full_path_for(path) [endpoint_namespace, path].join('').to_sym end def url_for(path) [base_url, full_path_for(path)].join('').to_sym end end end end