Module: ConvenientScopes

Includes:
ScopeDefinitions
Defined in:
lib/convenient_scopes.rb

Defined Under Namespace

Modules: ScopeDefinitions Classes: InvalidScopes

Constant Summary

Constants included from ScopeDefinitions

ScopeDefinitions::ORDERING_SCOPE_DEFINITIONS, ScopeDefinitions::SCOPE_DEFINITIONS, ScopeDefinitions::SCOPE_WITHOUT_VALUE_DEFINITIONS

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ScopeDefinitions

#boolean_column_scopes, #equals_scope, #ordering_scopes, #scopes_with_value, #scopes_without_value

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



25
26
27
28
29
30
31
32
# File 'lib/convenient_scopes.rb', line 25

def method_missing name, *args, &block
  if scope_data = (define_scope name, unscoped)
    scope name, convert_to_scope_arg(scope_data)
    send name, *args, &block
  else
    super
  end
end

Class Method Details

.extended(base) ⇒ Object



3
4
5
6
# File 'lib/convenient_scopes.rb', line 3

def self.extended base
  base.class_attribute :scopes
  base.scopes = {}
end

Instance Method Details

#ar_relation_methods?(name) ⇒ Boolean

Returns:

  • (Boolean)


53
54
55
56
# File 'lib/convenient_scopes.rb', line 53

def ar_relation_methods? name
  (ActiveRecord::Relation::MULTI_VALUE_METHODS + ActiveRecord::Relation::SINGLE_VALUE_METHODS +
  ActiveRecord::Relation::ASSOCIATION_METHODS).include? name
end

#define_scope(name, unscoped = nil) ⇒ Object



34
35
36
37
38
39
# File 'lib/convenient_scopes.rb', line 34

def define_scope name, unscoped = nil
  unscoped ||= self.unscoped
  (ScopeDefinitions.instance_methods.inject nil do |memo, scope_type|
    memo ||= send scope_type.to_sym, name, unscoped
  end) || (association_scope name, unscoped)
end

#determine_order_scope_data(name, direction, unscoped) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'lib/convenient_scopes.rb', line 58

def determine_order_scope_data name, direction, unscoped
  if column_names.include? name.to_s
    unscoped.order("#{quoted_table_name}.#{name} #{direction}")
  elsif assoc = (possible_association_for_scope name)
    next_scope = extract_next_scope name, assoc
    scope_arg = assoc.klass.determine_order_scope_data next_scope, direction, unscoped
    scope_arg.is_a?(Array) ? [assoc.name] + scope_arg : [assoc.name, scope_arg] if scope_arg
  end
end

#scope(name, scope_options = {}) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/convenient_scopes.rb', line 8

def scope(name, scope_options = {})
  name = name.to_sym
  valid_scope_name?(name)
  extension = Module.new(&Proc.new) if block_given?

  scopes[name] = lambda do |*args|
    options = scope_options.respond_to?(:call) ? scope_options.call(*args) : scope_options
    options = scoped.apply_finder_options(options) if options.is_a?(Hash)

    relation = scoped.merge(options)

    extension ? relation.extending(extension) : relation
  end

  singleton_class.send(:redefine_method, name, &scopes[name])
end

#search(search_scopes) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/convenient_scopes.rb', line 41

def search search_scopes
  res = scoped
  search_scopes.each do |name, args|
    if scopes.keys.include?(name.to_sym) || ar_relation_methods?(name) || !respond_to?(name)
      res = res.send name, args unless args == false
    else
      raise InvalidScopes
    end
  end
  res
end