Skip to content
This repository
Browse code

Renamed from ListMixin and mixins/list_mixin.rb to Mixins::List and m…

…ixin/list.rb

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@83 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 55be0a3cb518b345fa659629c4f2829faf745fab 1 parent 2d483af
David Heinemeier Hansson dhh authored
2  activerecord/lib/active_record.rb
@@ -45,6 +45,8 @@
45 45 include ActiveRecord::Reflection
46 46 end
47 47
  48 +require 'active_record/mixins/list'
  49 +
48 50 require 'active_record/connection_adapters/mysql_adapter'
49 51 require 'active_record/connection_adapters/postgresql_adapter'
50 52 require 'active_record/connection_adapters/sqlite_adapter'
155 activerecord/lib/active_record/mixins/list.rb
... ... @@ -0,0 +1,155 @@
  1 +module ActiveRecord
  2 + module Mixins
  3 + # This mixin provides the capabilities for sorting and reordering a number of objects in list.
  4 + # The class that has this mixin included needs to have a "position" column defined as an integer on
  5 + # the mapped database table. Further more, you need to implement the <tt>scope_condition</tt> that
  6 + # defines how to separate one list from another.
  7 + #
  8 + # Todo list example:
  9 + #
  10 + # class TodoList < ActiveRecord::Base
  11 + # has_many :todo_items, :order => "position"
  12 + # end
  13 + #
  14 + # class TodoItem < ActiveRecord::Base
  15 + # include ListMixin
  16 + # belongs_to :todo_list
  17 + #
  18 + # private
  19 + # def scope_condition
  20 + # "todo_list_id = #{todo_list_id}"
  21 + # end
  22 + # end
  23 + #
  24 + # todo_list.first.move_to_bottom
  25 + # todo_list.last.move_higher
  26 + module List
  27 + def self.append_features(base)
  28 + super
  29 + base.class_eval do
  30 + before_destroy :remove_from_list
  31 + after_create :add_to_list_bottom
  32 + end
  33 + end
  34 +
  35 + # Moving around on the list
  36 +
  37 + def move_lower
  38 + return unless lower_item
  39 + lower_item.decrement_position
  40 + increment_position
  41 + end
  42 +
  43 + def move_higher
  44 + return unless higher_item
  45 + higher_item.increment_position
  46 + decrement_position
  47 + end
  48 +
  49 + def move_to_bottom
  50 + decrement_positions_on_lower_items
  51 + assume_bottom_position
  52 + end
  53 +
  54 + def move_to_top
  55 + increment_positions_on_higher_items
  56 + assume_top_position
  57 + end
  58 +
  59 +
  60 + # Entering or existing the list
  61 +
  62 + def add_to_list_top
  63 + increment_positions_on_all_items
  64 + end
  65 +
  66 + def add_to_list_bottom
  67 + assume_bottom_position
  68 + end
  69 +
  70 + def remove_from_list
  71 + decrement_positions_on_lower_items
  72 + end
  73 +
  74 +
  75 + # Changing the position
  76 +
  77 + def increment_position
  78 + self.position = position.to_i + 1
  79 + save
  80 + end
  81 +
  82 + def decrement_position
  83 + self.position = position.to_i - 1
  84 + save
  85 + end
  86 +
  87 +
  88 + # Querying the position
  89 +
  90 + def first?
  91 + self.position == 1
  92 + end
  93 +
  94 + def last?
  95 + self.position == bottom_position_in_list
  96 + end
  97 +
  98 + private
  99 + # Overwrite this method to define the scope of the list changes
  100 + def scope_condition; end
  101 +
  102 + def higher_item
  103 + self.class.find_first(
  104 + "#{scope_condition} AND position = #{(position.to_i - 1).to_s}"
  105 + )
  106 + end
  107 +
  108 + def lower_item
  109 + self.class.find_first(
  110 + "#{scope_condition} AND position = #{(position.to_i + 1).to_s}"
  111 + )
  112 + end
  113 +
  114 + def bottom_position_in_list
  115 + item = bottom_item
  116 + item ? item.position : 0
  117 + end
  118 +
  119 + def bottom_item
  120 + self.class.find_first(
  121 + "#{scope_condition} ",
  122 + "position DESC"
  123 + )
  124 + end
  125 +
  126 + def assume_bottom_position
  127 + self.position = bottom_position_in_list.to_i + 1
  128 + save
  129 + end
  130 +
  131 + def assume_top_position
  132 + self.position = 1
  133 + save
  134 + end
  135 +
  136 + def decrement_positions_on_lower_items
  137 + self.class.update_all(
  138 + "position = (position - 1)", "#{scope_condition} AND position > #{position.to_i}"
  139 + )
  140 + end
  141 +
  142 + def increment_positions_on_higher_items
  143 + self.class.update_all(
  144 + "position = (position + 1)", "#{scope_condition} AND position < #{position.to_i}"
  145 + )
  146 + end
  147 +
  148 + def increment_positions_on_all_items
  149 + self.class.update_all(
  150 + "position = (position + 1)", "#{scope_condition}"
  151 + )
  152 + end
  153 + end
  154 + end
  155 +end
154 activerecord/lib/active_record/mixins/list_mixin.rb
... ... @@ -1,154 +0,0 @@
1   -module ActiveRecord
2   - # This mixin provides the capabilities for sorting and reordering a number of objects in list.
3   - # The class that has this mixin included needs to have a "position" column defined as an integer on
4   - # the mapped database table. Further more, you need to implement the <tt>scope_condition</tt> that
5   - # defines how to separate one list from another.
6   - #
7   - # Todo list example:
8   - #
9   - # class TodoList < ActiveRecord::Base
10   - # has_many :todo_items, :order => "position"
11   - # end
12   - #
13   - # class TodoItem < ActiveRecord::Base
14   - # include ListMixin
15   - # belongs_to :todo_list
16   - #
17   - # private
18   - # def scope_condition
19   - # "todo_list_id = #{todo_list_id}"
20   - # end
21   - # end
22   - #
23   - # todo_list.first.move_to_bottom
24   - # todo_list.last.move_higher
25   - #
26   - module ListMixin
27   - def self.append_features(base)
28   - super
29   - base.class_eval do
30   - before_destroy :remove_from_list
31   - after_create :add_to_list_bottom
32   - end
33   - end
34   -
35   - # Moving around on the list
36   -
37   - def move_lower
38   - return unless lower_item
39   - lower_item.decrement_position
40   - increment_position
41   - end
42   -
43   - def move_higher
44   - return unless higher_item
45   - higher_item.increment_position
46   - decrement_position
47   - end
48   -
49   - def move_to_bottom
50   - decrement_positions_on_lower_items
51   - assume_bottom_position
52   - end
53   -
54   - def move_to_top
55   - increment_positions_on_higher_items
56   - assume_top_position
57   - end
58   -
59   -
60   - # Entering or existing the list
61   -
62   - def add_to_list_top
63   - increment_positions_on_all_items
64   - end
65   -
66   - def add_to_list_bottom
67   - assume_bottom_position
68   - end
69   -
70   - def remove_from_list
71   - decrement_positions_on_lower_items
72   - end
73   -
74   -
75   - # Changing the position
76   -
77   - def increment_position
78   - self.position = position.to_i + 1
79   - save
80   - end
81   -
82   - def decrement_position
83   - self.position = position.to_i - 1
84   - save
85   - end
86   -
87   -
88   - # Querying the position
89   -
90   - def first?
91   - self.position == 1
92   - end
93   -
94   - def last?
95   - self.position == bottom_position_in_list
96   - end
97   -
98   - private
99   - # Overwrite this method to define the scope of the list changes
100   - def scope_condition; end
101   -
102   - def higher_item
103   - self.class.find_first(
104   - "#{scope_condition} AND position = #{(position.to_i - 1).to_s}"
105   - )
106   - end
107   -
108   - def lower_item
109   - self.class.find_first(
110   - "#{scope_condition} AND position = #{(position.to_i + 1).to_s}"
111   - )
112   - end
113   -
114   - def bottom_position_in_list
115   - item = bottom_item
116   - item ? item.position : 0
117   - end
118   -
119   - def bottom_item
120   - self.class.find_first(
121   - "#{scope_condition} ",
122   - "position DESC"
123   - )
124   - end
125   -
126   - def assume_bottom_position
127   - self.position = bottom_position_in_list.to_i + 1
128   - save
129   - end
130   -
131   - def assume_top_position
132   - self.position = 1
133   - save
134   - end
135   -
136   - def decrement_positions_on_lower_items
137   - self.class.update_all(
138   - "position = (position - 1)", "#{scope_condition} AND position > #{position.to_i}"
139   - )
140   - end
141   -
142   - def increment_positions_on_higher_items
143   - self.class.update_all(
144   - "position = (position + 1)", "#{scope_condition} AND position < #{position.to_i}"
145   - )
146   - end
147   -
148   - def increment_positions_on_all_items
149   - self.class.update_all(
150   - "position = (position + 1)", "#{scope_condition}"
151   - )
152   - end
153   - end
154   -end

0 comments on commit 55be0a3

Please sign in to comment.
Something went wrong with that request. Please try again.