Module: Huberry::Sortable::InstanceMethods

Defined in:
lib/sortable.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



156
157
158
159
160
161
162
163
# File 'lib/sortable.rb', line 156

def self.included(base)
  base.class_eval do
    before_create :add_to_lists
    before_update :update_lists
    after_destroy :remove_from_lists
    alias_method_chain :reload, :sortable
  end
end

Instance Method Details

#add_to_list!(list_name = nil) ⇒ Object

Adds the current item to the end of the specified list and saves

If the current item is already in the list, it will remove it before adding it



168
169
170
171
172
# File 'lib/sortable.rb', line 168

def add_to_list!(list_name = nil)
  remove_from_list!(list_name) if in_list?(list_name)
  add_to_list(list_name)
  save
end

#first_item(list_name = nil) ⇒ Object

Returns the first item in a list associated with the current item



175
176
177
178
# File 'lib/sortable.rb', line 175

def first_item(list_name = nil)
  options = evaluate_sortable_options(list_name)
  self.class.base_class.send("find_by_#{options[:column]}".to_sym, 1, :conditions => options[:conditions])
end

#first_item?(list_name = nil) ⇒ Boolean

Returns a boolean after determining if the current item is the first item in the specified list



181
182
183
# File 'lib/sortable.rb', line 181

def first_item?(list_name = nil)
  self == first_item(list_name)
end

#higher_items(list_name = nil) ⇒ Object

Returns an array of items higher than the current item in the specified list



186
187
188
189
190
191
# File 'lib/sortable.rb', line 186

def higher_items(list_name = nil)
  options = evaluate_sortable_options(list_name)
  options[:conditions].first << " AND #{self.class.table_name}.#{options[:column]} < ?"
  options[:conditions] << send(options[:column])
  self.class.base_class.find(:all, :conditions => options[:conditions], :order => options[:column])
end

#in_list?(list_name = nil) ⇒ Boolean

Returns a boolean after determining if the current item is in the specified list



194
195
196
# File 'lib/sortable.rb', line 194

def in_list?(list_name = nil)
  !new_record? && !send(evaluate_sortable_options(list_name)[:column]).nil?
end

#insert_at!(position = 1, list_name = nil) ⇒ Object Also known as: insert_at_position!

Inserts the current item at a certain position in the specified list and saves

If the current item is already in the list, it will remove it before adding it

Also aliased as insert_at_position!



203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/sortable.rb', line 203

def insert_at!(position = 1, list_name = nil)
  position = position.to_s.to_i
  if position > 0
    remove_from_list!(list_name)
    if position > last_position(list_name)
      add_to_list!(list_name)
    else
      move_lower_items(:down, position - 1, list_name)
      send("#{evaluate_sortable_options(list_name)[:column]}=".to_sym, position)
      save
    end
  end
end

#item_at_offset(offset, list_name = nil) ⇒ Object

Returns the item with a position at a certain offset to the current item's position in the specified list

Example

@todo = Todo.create
@todo_2 = Todo.create
@todo.item_at_offset(1) # returns @todo_2

Returns nil if an item at the specified offset could not be found



227
228
229
230
# File 'lib/sortable.rb', line 227

def item_at_offset(offset, list_name = nil)
  options = evaluate_sortable_options(list_name)
  in_list?(list_name) ? self.class.base_class.send("find_by_#{options[:column]}".to_sym, send(options[:column]) + offset.to_s.to_i, :conditions => options[:conditions]) : nil
end

#last_item(list_name = nil) ⇒ Object

Returns the last item in a list associated with the current item



233
234
235
236
237
238
# File 'lib/sortable.rb', line 233

def last_item(list_name = nil)
  options = evaluate_sortable_options(list_name)
  options[:conditions].first << " AND #{self.class.table_name}.#{options[:column]} IS NOT NULL"
  klass, conditions = [self.class.base_class, { :conditions => options[:conditions] }]
  klass.send("find_by_#{options[:column]}".to_sym, klass.maximum(options[:column], conditions), conditions)
end

#last_item?(list_name = nil) ⇒ Boolean

Returns a boolean after determining if the current item is the last item in the specified list



241
242
243
# File 'lib/sortable.rb', line 241

def last_item?(list_name = nil)
  self == last_item(list_name)
end

#last_position(list_name = nil) ⇒ Object

Returns the position of the last item in a specified list

Returns 0 if there are no items in the specified list



248
249
250
251
# File 'lib/sortable.rb', line 248

def last_position(list_name = nil)
  item = last_item(list_name)
  item.nil? ? 0 : item.send(evaluate_sortable_options(list_name)[:column])
end

#lower_items(list_name = nil) ⇒ Object

Returns an array of items lower than the current item in the specified list



254
255
256
257
258
259
# File 'lib/sortable.rb', line 254

def lower_items(list_name = nil)
  options = evaluate_sortable_options(list_name)
  options[:conditions].first << " AND #{self.class.table_name}.#{options[:column]} > ?"
  options[:conditions] << send(options[:column])
  self.class.base_class.find(:all, :conditions => options[:conditions], :order => "#{self.class.table_name}.#{options[:column]}")
end

#move_down!(list_name = nil) ⇒ Object

Moves the current item down one position in the specified list and saves



262
263
264
# File 'lib/sortable.rb', line 262

def move_down!(list_name = nil)        
  in_list?(list_name) && (last_item?(list_name) || insert_at!(send(evaluate_sortable_options(list_name)[:column]) + 1, list_name))
end

#move_to_bottom!(list_name = nil) ⇒ Object

Moves the current item down to the bottom of the specified list and saves



272
273
274
# File 'lib/sortable.rb', line 272

def move_to_bottom!(list_name = nil)
  in_list?(list_name) && (last_item?(list_name) || add_to_list!(list_name))
end

#move_to_top!(list_name = nil) ⇒ Object

Moves the current item up to the top of the specified list and saves



277
278
279
# File 'lib/sortable.rb', line 277

def move_to_top!(list_name = nil)
  in_list?(list_name) && (first_item?(list_name) || insert_at!(1, list_name))
end

#move_up!(list_name = nil) ⇒ Object

Moves the current item up one position in the specified list and saves



267
268
269
# File 'lib/sortable.rb', line 267

def move_up!(list_name = nil)
  in_list?(list_name) && (first_item?(list_name) || insert_at!(send(evaluate_sortable_options(list_name)[:column]) - 1, list_name))
end

#next_item(list_name = nil) ⇒ Object

Returns the next lower item in the specified list



282
283
284
# File 'lib/sortable.rb', line 282

def next_item(list_name = nil)
  item_at_offset(1, list_name)
end

#previous_item(list_name = nil) ⇒ Object

Returns the previous higher item in the specified list



287
288
289
# File 'lib/sortable.rb', line 287

def previous_item(list_name = nil)
  item_at_offset(-1, list_name)
end

#reload_with_sortable(*args) ⇒ Object

Clears any sortable_scope_changes and reloads normally



292
293
294
295
# File 'lib/sortable.rb', line 292

def reload_with_sortable(*args)
  @sortable_scope_changes = nil
  reload_without_sortable(*args)
end

#remove_from_list!(list_name = nil) ⇒ Object

Removes the current item from the specified list and saves

This will set the position to nil



300
301
302
303
304
305
306
307
# File 'lib/sortable.rb', line 300

def remove_from_list!(list_name = nil)
  if in_list?(list_name)
    remove_from_list(list_name)
    save
  else
    false
  end
end

#sortable_scope_changed?Boolean

Returns a boolean after determining if this item has changed any attributes specified in the :scope options



310
311
312
# File 'lib/sortable.rb', line 310

def sortable_scope_changed?
  !sortable_scope_changes.empty?
end

#sortable_scope_changesObject

Stores an array of attributes specified as a :scope that have been changed



315
316
317
# File 'lib/sortable.rb', line 315

def sortable_scope_changes
  @sortable_scope_changes ||= []
end