Class: MassiveRecord::ORM::Finders::Scope

Inherits:
Object
  • Object
show all
Defined in:
lib/massive_record/orm/finders/scope.rb

Overview

A finder scope’s jobs is to contain and build up limitations and meta data of a DB query about to being executed, allowing us to call for instance

User.select(:info).limit(5) or User.select(:info).find(a_user_id)

Each call adds restrictions or info about the query about to be executed, and the proxy will act as an Enumerable object when asking for multiple values

Constant Summary collapse

MULTI_VALUE_METHODS =
%w(select)
SINGLE_VALUE_METHODS =
%w(limit starts_with offset)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ Scope

Returns a new instance of Scope.



30
31
32
33
34
35
36
37
# File 'lib/massive_record/orm/finders/scope.rb', line 30

def initialize(klass)
  @klass = klass
  @extra_finder_options = {}

  reset
  reset_single_values_options
  reset_multi_values_options
end

Instance Attribute Details

#extra_finder_optionsObject

Returns the value of attribute extra_finder_options.



23
24
25
# File 'lib/massive_record/orm/finders/scope.rb', line 23

def extra_finder_options
  @extra_finder_options
end

#klassObject

Returns the value of attribute klass.



23
24
25
# File 'lib/massive_record/orm/finders/scope.rb', line 23

def klass
  @klass
end

#loadedObject Also known as: loaded?

Returns the value of attribute loaded.



23
24
25
# File 'lib/massive_record/orm/finders/scope.rb', line 23

def loaded
  @loaded
end

Instance Method Details

#==(other) ⇒ Object



80
81
82
83
84
85
86
87
88
89
# File 'lib/massive_record/orm/finders/scope.rb', line 80

def ==(other)
  case other
  when Scope
    object_id == other.object_id
  when Array
    to_a == other
  else
    raise "Don't know how to compare #{self.class} with #{other.class}"
  end
end

#all(options = {}) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/massive_record/orm/finders/scope.rb', line 103

def all(options = {})
  if options.empty?
    to_a
  else
    apply_finder_options(options).to_a
  end
end

#apply_finder_options(options) ⇒ Object

Takes a hash of finder options, applies them to a new scope and returns a that scope.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/massive_record/orm/finders/scope.rb', line 137

def apply_finder_options(options)
  scope = clone
  return scope if options.empty?

  options.each do |scope_method, arguments|
    if respond_to? scope_method
      scope = scope.send(scope_method, arguments)
    else
      scope.extra_finder_options[scope_method] = arguments              
    end
  end

  scope
end

#find(*args) ⇒ Object



93
94
95
96
97
98
99
100
101
# File 'lib/massive_record/orm/finders/scope.rb', line 93

def find(*args)
  options = args.extract_options!.to_options
  
  if options.any?
    apply_finder_options(options).find(*args)
  else
    klass.do_find(*args << find_options)
  end
end

#first(options = {}) ⇒ Object



111
112
113
114
115
116
117
# File 'lib/massive_record/orm/finders/scope.rb', line 111

def first(options = {})
  if loaded? && options.empty?
    @records.first
  else
    apply_finder_options(options).limit(1).to_a.first
  end
end

#initialize_copy(old) ⇒ Object



39
40
41
# File 'lib/massive_record/orm/finders/scope.rb', line 39

def initialize_copy(old)
  reset
end

#last(*args) ⇒ Object



119
120
121
# File 'lib/massive_record/orm/finders/scope.rb', line 119

def last(*args)
  raise "Sorry, but query last requires all records to be fetched. If you really want to do this, do an scope.all.last instead."
end

#limit(limit) ⇒ Object

Single value options



64
65
66
# File 'lib/massive_record/orm/finders/scope.rb', line 64

def limit(limit)
  cloned_version_with { self.limit_value = limit }
end

#offset(offset) ⇒ Object



72
73
74
# File 'lib/massive_record/orm/finders/scope.rb', line 72

def offset(offset)
  cloned_version_with { self.offset_value = offset }
end

#resetObject



44
45
46
47
# File 'lib/massive_record/orm/finders/scope.rb', line 44

def reset
  @loaded = false
  @records = []
end

#select(*select) ⇒ Object

Multi value options



55
56
57
# File 'lib/massive_record/orm/finders/scope.rb', line 55

def select(*select)
  cloned_version_with { self.select_values |= select.flatten.compact.collect(&:to_s) }
end

#starts_with(starts_with) ⇒ Object



68
69
70
# File 'lib/massive_record/orm/finders/scope.rb', line 68

def starts_with(starts_with)
  cloned_version_with { self.starts_with_value = starts_with }
end

#to_aObject



125
126
127
128
129
130
# File 'lib/massive_record/orm/finders/scope.rb', line 125

def to_a
  return @records if loaded?
  @records = load_records
  @records = [@records] unless @records.is_a? Array
  @records
end