Module: Resort::Sortable::InstanceMethods

Defined in:
lib/resort.rb

Overview

Instance methods to use.

Instance Method Summary collapse

Instance Method Details

#append_to(another) ⇒ Object

Puts the object right after another object in the list.



175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/resort.rb', line 175

def append_to(another)
  self.class.transaction do
    self.lock!
    return if another.next_id == id
    another.lock!
    delete_from_list
    if self.next_id or (another && another.next_id)
      raise(ActiveRecord::RecordNotSaved) unless self.update_attribute(:next_id, another.next_id)
    end
    if another
      raise(ActiveRecord::RecordNotSaved) unless another.update_attribute(:next_id, self.id)
    end
  end
end

#include_in_list!Object

Includes the object in the linked list.

If there are no other objects, it prepends the object so that it is in the first position. Otherwise, it appends it to the end of the empty list.



143
144
145
146
147
148
149
# File 'lib/resort.rb', line 143

def include_in_list!
  self.class.transaction do
    self.lock!
    _siblings.count > 0 ? last!\
                        : prepend
  end
end

#prependObject

Puts the object in the first position of the list.



152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/resort.rb', line 152

def prepend
  self.class.transaction do
    self.lock!
    return if first?
    if _siblings.count > 0
      delete_from_list
      old_first = _siblings.first_in_order
      raise(ActiveRecord::RecordNotSaved) unless self.update_attribute(:next_id, old_first.id)
      raise(ActiveRecord::RecordNotSaved) unless old_first.update_attribute(:first, false)
    end
    raise(ActiveRecord::RecordNotSaved) unless self.update_attribute(:first, true)
  end
end

#pushObject

Puts the object in the last position of the list.



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

def push
  self.class.transaction do
    self.lock!
    self.append_to(_siblings.last_in_order) unless last?
  end
end

#siblingsActiveRecord::Relation

Default definition of siblings, i.e. every instance of the model.

Can be overriden to specify a different scope for the siblings. For example, if we wanted to limit a products tree inside a ProductLine scope, we would do the following:

class Product < ActiveRecord::Base
  belongs_to :product_line

  resort!

  def siblings
    self.product_line.products
  end

This way, every product line is an independent tree of sortable products.

Returns:

  • (ActiveRecord::Relation)

    the element’s siblings relation.



135
136
137
# File 'lib/resort.rb', line 135

def siblings
  self.class.scoped
end