Module: ActiveRecord::Acts::List::ClassMethods

Defined in:
lib/acts_as_list/active_record/acts/list.rb

Overview

This acts_as extension provides the capabilities for sorting and reordering a number of objects in a list. The class that has this specified needs to have a position column defined as an integer on the mapped database table.

Todo list example:

class TodoList < ActiveRecord::Base
  has_many :todo_items, :order => "position"
end

class TodoItem < ActiveRecord::Base
  belongs_to :todo_list
  acts_as_list :scope => :todo_list
end

todo_list.first.move_to_bottom
todo_list.last.move_higher

Instance Method Summary collapse

Instance Method Details

#acts_as_list(options = {}) ⇒ Object

Configuration options are:

  • column - specifies the column name to use for keeping the position integer (default: position)

  • scope - restricts what is to be considered a list. Given a symbol, it’ll attach _id (if it hasn’t already been added) and use that as the foreign key restriction. It’s also possible to give it an entire string that is interpolated if you need a tighter scope than just a foreign key. Example: acts_as_list :scope => 'todo_list_id = #{todo_list_id} AND completed = 0'

  • top_of_list - defines the integer used for the top of the list. Defaults to 1. Use 0 to make the collection act more line an array in it’s indexing.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/acts_as_list/active_record/acts/list.rb', line 35

def acts_as_list(options = {})
  configuration = { :column => "position", :scope => "1 = 1", :top_of_list => 1}
  configuration.update(options) if options.is_a?(Hash)

  configuration[:scope] = "#{configuration[:scope]}_id".intern if configuration[:scope].is_a?(Symbol) && configuration[:scope].to_s !~ /_id$/

  if configuration[:scope].is_a?(Symbol)
    scope_condition_method = %(
      def scope_condition
        self.class.send(:sanitize_sql_hash_for_conditions, { :#{configuration[:scope].to_s} => send(:#{configuration[:scope].to_s}) })
      end
    )
  elsif configuration[:scope].is_a?(Array)
    scope_condition_method = %(
      def scope_condition
        attrs = %w(#{configuration[:scope].join(" ")}).inject({}) do |memo,column| 
          memo[column.intern] = send(column.intern); memo
        end
        self.class.send(:sanitize_sql_hash_for_conditions, attrs)
      end
    )
  else
    scope_condition_method = "def scope_condition() \"#{configuration[:scope]}\" end"
  end

  class_eval <<-EOV
    include ActiveRecord::Acts::List::InstanceMethods

    def acts_as_list_top
      #{configuration[:top_of_list]}.to_i
    end

    def acts_as_list_class
      ::#{self.name}
    end

    def position_column
      '#{configuration[:column]}'
    end

    #{scope_condition_method}

    before_destroy :decrement_positions_on_lower_items
    before_create  :add_to_list_bottom
  EOV
end