Sha256: 9c43b5d645599ce919660bc5e73a8e4471d99a4ec3c68d96f09e519cb70a8931

Contents?: true

Size: 1.98 KB

Versions: 3

Compression:

Stored size: 1.98 KB

Contents

require 'action_controller/base'

module Emerson
  # Add helpers for request-base, scoped resource loading.
  module Scope
    def self.included(base)
      base.class_eval do
        extend ClassMethods
        # TODO: consider...
        # helper_method :current_scope
        class_attribute :scope_configuration
      end
    end

    module ClassMethods
      def scope(*args)
        options   = args.extract_options!
        resources = args.shift

        unless options.key?(:by)
          raise ArgumentError.new(".scopes requires a :by option")
        end

        unless resources.present?
          raise ArgumentError.new(".scopes requires a (plural) resources type")
        end

        self.scope_configuration   ||= [resources, []]
        self.scope_configuration[1] += [options[:by]].flatten
        self.scope_configuration[1].uniq!
      end
    end

    def scoped(explicit = nil)
      @_scoped ||= begin
        if scope_configuration.present?
          target = scope_configuration.first

          if explicit.present?
            @scope = explicit
            @scope.send(target)
          elsif scope = scope_from_params
            @scope = scope
            @scope.send(target)
          else
            @scope = nil # be explicit
            class_for(singular(target)).scoped
          end
        else
          @scope = nil # be explicit
          default_scope
        end
      end
    end

    def current_scope
      scoped && @scope
    end

    protected

      def scope_from_params
        param = nil
        type  = self.scope_configuration.last.find { |scope| (param = params["#{scope}_id"]) && param }

        return nil unless type

        class_for(type).find(param)
      end

    private

      def class_for(type)
        type.to_s.classify.constantize
      end

      def default_scope
        klass = class_for(singular(self.class.name.sub(/Controller$/, '')))
        klass.scoped
      end

      def singular(plural)
        plural.to_s.singularize
      end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
emerson-0.1.0.pre.4 lib/emerson/scope.rb
emerson-0.1.0.pre.3 lib/emerson/scope.rb
emerson-0.1.0.pre.2 lib/emerson/scope.rb