module CollectionScope extend ActiveSupport::Concern private def scope raise NotImplementedError, 'Please override #scope when you use CollectionScope' end def default_per_page 20 end def max_per_page 250 end def per_page # allow max_per_page and default_per_page to be nil as well if params[:per_page] [params[:per_page].to_i, max_per_page].compact.min else default_per_page end end def search_scope s = scope s = s.ransack(params[:q], auth_object: ransack_auth_object).result(distinct: true) if params[:q] s = s.page(params[:page].to_i).per(per_page) if per_page && per_page >= 0 s end def render_collection(scope) render json: scope, meta: collection_meta(scope) end def collection_meta(scope, extra = {}) return unless scope.respond_to?(:total_count) && per_page { page: params[:page].to_i, per_page: per_page, total_pages: (scope.total_count / [1, per_page].max).ceil, total_count: scope.total_count }.merge(extra) end # By default, there are no special ransack search scope authentications. # Controllers can override this to return something else and customize a model's # +ransackable_attributes+ and +ransackable_associations+ to allow searching on more # parameters in one controller than another (e.g. to protect searches that are scoped # to a user, while still allowing all search parameters for another endpoint). def ransack_auth_object nil end end