Module: Sequel::Plugins::Sequenceable::InstanceMethods

Defined in:
lib/cortex_reaver/support/sequenceable.rb

Instance Method Summary collapse

Instance Method Details

#absolute_window_index(size = self.class.window_size) ⇒ Object

Returns the absolute window index that this record appears in



241
242
243
# File 'lib/cortex_reaver/support/sequenceable.rb', line 241

def absolute_window_index(size = self.class.window_size)
  (Float(self.position) / size).floor
end

#absolute_window_url(size = self.class.window_size) ⇒ Object

Returns a url for this record, viewed in an absolute window. TODO: handle non-default window sizes.



234
235
236
237
238
# File 'lib/cortex_reaver/support/sequenceable.rb', line 234

def absolute_window_url(size = self.class.window_size)
  page = (Float(position) / size).floor
  self.class.url + '/page/' + page.to_s + '#' + self.class.to_s.demodulize.underscore + 
    '_' + send(self.class.canonical_name_attr)
end

#next(refresh_cache = false) ⇒ Object

Returns the next record in the sequence. Caches–use next(true) to refresh.



115
116
117
118
119
120
121
# File 'lib/cortex_reaver/support/sequenceable.rb', line 115

def next(refresh_cache = false)
  if refresh_cache
    @next = sequence.filter{|o| o.__send__(sequence_order) > send(sequence_order)}.limit(1).first
  else
    @next ||= sequence.filter{|o| o.__send__(sequence_order) > send(sequence_order)}.limit(1).first
  end
end

#next?(refresh_cache = false) ⇒ Boolean

Returns true if a next record exists. Caches–use next(true) to refresh.

Returns:

  • (Boolean)


125
126
127
128
129
130
131
# File 'lib/cortex_reaver/support/sequenceable.rb', line 125

def next?(refresh_cache = false)
  if refresh_cache
    @next_exists ||= self.next_count > 0 ? true : false
  else
    @next_exists = self.next_count > 0 ? true : false
  end
end

#next_countObject

Returns the number of succeeding records



134
135
136
# File 'lib/cortex_reaver/support/sequenceable.rb', line 134

def next_count
  sequence.filter{|o| o.__send__(sequence_order) > send(sequence_order)}.count
end

#previous(refresh_cache = false) ⇒ Object

Returns the previous record in the sequence. Caches–use previous(true) to refresh.



140
141
142
143
144
145
146
# File 'lib/cortex_reaver/support/sequenceable.rb', line 140

def previous(refresh_cache = false)
  if refresh_cache
    @previous = sequence.filter{|o| p o; o.__send__(sequence_order) < send(sequence_order)}.reverse.limit(1).first
  else
    @previous ||= sequence.filter{|o| o.__send__(sequence_order) < send(sequence_order)}.reverse.limit(1).first
  end 
end

#previous?(refresh_cache = false) ⇒ Boolean

Returns true if a previous record exists. Caches–use previous?(true) to refresh.

Returns:

  • (Boolean)


150
151
152
153
154
155
156
# File 'lib/cortex_reaver/support/sequenceable.rb', line 150

def previous?(refresh_cache = false)
  if refresh_cache
    @previous_exists = self.previous_count > 0 ? true : false
  else
    @previous_exists ||= self.previous_count > 0 ? true : false
  end
end

#previous_countObject Also known as: position

Returns the number of preceding records



159
160
161
# File 'lib/cortex_reaver/support/sequenceable.rb', line 159

def previous_count
  sequence.filter{|o| o.__send__(sequence_order) < send(sequence_order)}.count
end

#sequenceObject

Convenience references to class methods



101
102
103
# File 'lib/cortex_reaver/support/sequenceable.rb', line 101

def sequence
  self.class.sequence
end

#sequence_orderObject



105
106
107
# File 'lib/cortex_reaver/support/sequenceable.rb', line 105

def sequence_order
  self.class.sequence_order
end

#sequence_reverseObject



109
110
111
# File 'lib/cortex_reaver/support/sequenceable.rb', line 109

def sequence_reverse
  self.class.sequence_reverse
end

#window(mode = :absolute, size = self.class.window_size) ⇒ Object

Returns a collection of records around this record. Mode is one of:

  1. :absolute Returns a window containing this record in even multiples from

    the first record, like a page of a book.
    
  2. :float Returns a centered window of the provided size. If the edge of

    the sequence is reached, the window shifts to include more
    elements of the sequence. If no more elements are available 
    (the window is larger than the size of the sequence), the 
    entire sequence is returned. If the size is even, one more
    record is returned suceeding this record than preceding this
    record, if possible.
    
  3. :clip Returns a centered window of or smaller than the given size. If

    the edge of the sequence is reached, the window is clipped.
    


178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/cortex_reaver/support/sequenceable.rb', line 178

def window(mode = :absolute, size = self.class.window_size)
  case mode
    when :absolute
      # Calculate page offset
      offset = (Float(position) / size).floor * size

      # Find records
      sequence.limit(size, offset)
    when :float
      count = sequence.count			# Total records
      if size >= count
        # Window includes all records in the sequence
        return self.class.find(:all)
      else
        # Window is smaller than the sequence
        position = self.position			              # This record's position
        previous_size = (Float(size - 1) / 2).floor	# How many records before
        next_size = (Float(size - 1) / 2).ceil		  # How many records after

        # Shift window if necessary
        if (displacement = previous_size - position) > 0
          # The window extends before the start of the sequence
          previous_size -= displacement
        elsif (displacement = next_size - self.next_count) > 0
          # The window extends beyond the end of the sequence
          previous_size += displacement
        end

        # Calculate window offset
        offset = position - previous_size

        # Find records
        sequence.limit(size, offset)
      end
    when :clip
      position = self.position                    # Our position in sequence
      previous_size = (Float(size - 1) / 2).floor # How many records before

      if (displacement = previous_size - position) > 0
        # The window extends before the beginning of the sequence
        size -= displacement
        offset = 0
      else
        # The window doesn't extend before the beginning of the sequence.
        offset = position - previous_size
      end

      # Find records.
      sequence.limit(size, offset)
    else
      raise ArgumentError.new('first argument must be one of :absolute, :float, :clip')
  end
end