aguids-positionable 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.document +5 -0
  2. data/.gitignore +11 -0
  3. data/LICENSE +20 -0
  4. data/README.markdown +200 -0
  5. data/Rakefile +56 -0
  6. data/VERSION +1 -0
  7. data/app/controllers/positionable_controller.rb +32 -0
  8. data/app/helpers/positionable_helper.rb +70 -0
  9. data/config/routes.rb +3 -0
  10. data/init.rb +1 -0
  11. data/lib/positionable.rb +362 -0
  12. data/positionable.gemspec +154 -0
  13. data/test/rails_root/Rakefile +10 -0
  14. data/test/rails_root/app/controllers/application_controller.rb +10 -0
  15. data/test/rails_root/app/helpers/application_helper.rb +3 -0
  16. data/test/rails_root/app/models/conditional_item.rb +3 -0
  17. data/test/rails_root/app/models/different_position_column_item.rb +3 -0
  18. data/test/rails_root/app/models/hell_on_earth_item.rb +5 -0
  19. data/test/rails_root/app/models/multiple_list_item.rb +5 -0
  20. data/test/rails_root/app/models/multiple_scoped_item.rb +3 -0
  21. data/test/rails_root/app/models/scoped_item.rb +3 -0
  22. data/test/rails_root/app/models/simple_item.rb +4 -0
  23. data/test/rails_root/config/boot.rb +110 -0
  24. data/test/rails_root/config/database.yml +22 -0
  25. data/test/rails_root/config/environment.rb +14 -0
  26. data/test/rails_root/config/environments/development.rb +17 -0
  27. data/test/rails_root/config/environments/production.rb +28 -0
  28. data/test/rails_root/config/environments/test.rb +28 -0
  29. data/test/rails_root/config/initializers/backtrace_silencers.rb +7 -0
  30. data/test/rails_root/config/initializers/inflections.rb +10 -0
  31. data/test/rails_root/config/initializers/mime_types.rb +5 -0
  32. data/test/rails_root/config/initializers/new_rails_defaults.rb +19 -0
  33. data/test/rails_root/config/initializers/session_store.rb +15 -0
  34. data/test/rails_root/config/locales/en.yml +5 -0
  35. data/test/rails_root/config/routes.rb +45 -0
  36. data/test/rails_root/db/development.sqlite3 +0 -0
  37. data/test/rails_root/db/migrate/20090702170207_create_simple_items.rb +13 -0
  38. data/test/rails_root/db/migrate/20090703071830_create_scoped_items.rb +14 -0
  39. data/test/rails_root/db/migrate/20090706180046_create_different_position_column_items.rb +13 -0
  40. data/test/rails_root/db/migrate/20090706200318_create_conditional_items.rb +14 -0
  41. data/test/rails_root/db/migrate/20090708045618_create_multiple_scoped_items.rb +15 -0
  42. data/test/rails_root/db/migrate/20090708174947_create_multiple_list_items.rb +15 -0
  43. data/test/rails_root/db/migrate/20090708183550_create_hell_on_earth_items.rb +19 -0
  44. data/test/rails_root/db/schema.rb +68 -0
  45. data/test/rails_root/script/about +4 -0
  46. data/test/rails_root/script/console +3 -0
  47. data/test/rails_root/script/dbconsole +3 -0
  48. data/test/rails_root/script/destroy +3 -0
  49. data/test/rails_root/script/generate +3 -0
  50. data/test/rails_root/script/performance/benchmarker +3 -0
  51. data/test/rails_root/script/performance/profiler +3 -0
  52. data/test/rails_root/script/plugin +3 -0
  53. data/test/rails_root/script/runner +3 -0
  54. data/test/rails_root/script/server +3 -0
  55. data/test/rails_root/test/conditional_tests.rb +28 -0
  56. data/test/rails_root/test/functional/positionable_controller_test.rb +50 -0
  57. data/test/rails_root/test/performance/browsing_test.rb +9 -0
  58. data/test/rails_root/test/scoped_tests.rb +53 -0
  59. data/test/rails_root/test/simple_gap_tests.rb +17 -0
  60. data/test/rails_root/test/simple_gapless_tests.rb +52 -0
  61. data/test/rails_root/test/simple_tests.rb +185 -0
  62. data/test/rails_root/test/test_helper.rb +37 -0
  63. data/test/rails_root/test/unit/conditional_item_test.rb +36 -0
  64. data/test/rails_root/test/unit/different_position_column_item_test.rb +21 -0
  65. data/test/rails_root/test/unit/eval_support_test.rb +62 -0
  66. data/test/rails_root/test/unit/hell_on_earth_item_test.rb +71 -0
  67. data/test/rails_root/test/unit/helpers/positionable_helper_test.rb +69 -0
  68. data/test/rails_root/test/unit/multiple_list_item_test.rb +60 -0
  69. data/test/rails_root/test/unit/multiple_scoped_item_test.rb +34 -0
  70. data/test/rails_root/test/unit/scoped_item_test.rb +22 -0
  71. data/test/rails_root/test/unit/scoped_item_with_gaps_test.rb +25 -0
  72. data/test/rails_root/test/unit/simple_item_test.rb +21 -0
  73. data/test/rails_root/test/unit/simple_item_with_gaps_test.rb +24 -0
  74. metadata +172 -0
@@ -0,0 +1,362 @@
1
+ module Positionable
2
+
3
+ # This +acts_as+ extension provides the capabilities for sorting and reordering a number of objects in a list.
4
+ # The class that has this specified needs to have a column defined as an integer on the mapped database table
5
+ # to store the list's position. The default is +position+.
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
+ # belongs_to :todo_list
15
+ # acts_as_positionable :scope => :todo_list_id
16
+ # end
17
+ #
18
+ # todo_list.first.move_to_bottom
19
+ # todo_list.last.move_higher
20
+ module ClassMethods
21
+ # Configuration options are:
22
+ #
23
+ # * +column+ - specifies the column name to use for keeping the position integer (default: +position+)
24
+ # * +scope+ - restricts what is to be considered a list. Expects a symbol representing a object attribute
25
+ # * +conditions+ - activerecord find conditions to evaluate if the record should be inserted on the list
26
+ # * +list_name+ - the name for this list's act_as_positionable declaration (default: +:default+)
27
+ def acts_as_positionable(options = {})
28
+ options = { :list_name => :default, :column => "position" }.merge(options)
29
+
30
+ cattr_accessor :positionable unless respond_to?(:positionable)
31
+ self.positionable ||= Positionable::Wrapper.new
32
+ self.positionable << options
33
+
34
+ named_scope :ascending, lambda { |list_name|
35
+ { :order => self.positionable.lists[list_name][:column] }
36
+ }
37
+ named_scope :descending, lambda { |list_name|
38
+ { :order => "#{self.positionable.lists[list_name][:column]} DESC" }
39
+ }
40
+ named_scope :conditions, lambda { |list_name|
41
+ { :conditions => self.positionable.lists[list_name][:conditions] }
42
+ }
43
+
44
+ class_eval <<-EOV
45
+ include Positionable::InstanceMethods
46
+
47
+ def acts_as_positionable_class
48
+ ::#{self.name}
49
+ end
50
+
51
+ before_create :add_to_lists
52
+ before_update :update_lists
53
+ before_destroy :remove_from_lists
54
+ EOV
55
+ end
56
+ end
57
+
58
+ module EvalSupport
59
+ def conditions_to_eval(conditions)
60
+ case conditions
61
+ when Array then array_conditions_to_eval(conditions)
62
+ when Hash then hash_conditions_to_eval(conditions)
63
+ when String then string_conditions_to_eval(conditions)
64
+ end
65
+ end
66
+
67
+ def array_conditions_to_eval(conditions)
68
+ string_conditions_to_eval ActiveRecord::Base.send(:sanitize_sql_array, conditions)
69
+ end
70
+
71
+ def hash_conditions_to_eval(conditions)
72
+ conditions.inject("") do |str, (attribute, value)|
73
+ str << ' && ' unless str.blank?
74
+ str << "#{attribute} == "
75
+ str << case value
76
+ when String then "\'#{value}\'"
77
+ when nil then 'nil'
78
+ else value.to_s
79
+ end
80
+ end
81
+ end
82
+
83
+ def string_conditions_to_eval(conditions)
84
+ conditions.gsub(' = ', ' == ').gsub(/ and /i, ' && ').gsub(/ or /i, ' || ')
85
+ end
86
+
87
+ module_function :conditions_to_eval, :array_conditions_to_eval, :hash_conditions_to_eval, :string_conditions_to_eval
88
+ end
89
+
90
+ # Wrapper class for all the lists' options
91
+ class Wrapper
92
+ attr_accessor :lists
93
+ def initialize
94
+ self.lists = {}
95
+ end
96
+
97
+ def <<(options={})
98
+ options[:conditions_to_eval] = Positionable::EvalSupport.conditions_to_eval(options[:conditions])
99
+ self.lists[options.delete(:list_name)] = options
100
+ end
101
+
102
+ def has_scope?(list_name)
103
+ !!lists[list_name][:scope]
104
+ end
105
+
106
+ def scope(list_name)
107
+ lists[list_name][:scope].is_a?(Array) ? lists[list_name][:scope] : [lists[list_name][:scope]]
108
+ end
109
+
110
+ def has_conditions?(list_name)
111
+ !!lists[list_name][:conditions]
112
+ end
113
+
114
+ def conditions(list_name)
115
+ lists[list_name][:conditions]
116
+ end
117
+ end
118
+
119
+ # All the methods available to a record that has had <tt>acts_as_positionable</tt> specified. Each method works
120
+ # by assuming the object to be the item in the list, so <tt>chapter.move_lower</tt> would move that chapter
121
+ # lower in the list of all chapters. Likewise, <tt>chapter.first?</tt> would return +true+ if that chapter is
122
+ # the first in the list of all chapters.
123
+ module InstanceMethods
124
+ # Insert the item at the given position (defaults to the top position).
125
+ def insert_at(position = :top, list_name = :default)
126
+ if !position.is_a?(Symbol) && position <= 0
127
+ position = :top
128
+ elsif !position.is_a?(Symbol) && position > bottom_position_in_list(list_name) && position != 1
129
+ position = :bottom
130
+ end
131
+ insert_at_position(list_name, position)
132
+ end
133
+
134
+ def insert_at_top(list_name = :default)
135
+ insert_at_position(list_name, :top)
136
+ end
137
+
138
+ def insert_at_bottom(list_name = :default)
139
+ insert_at_position(list_name, :bottom)
140
+ end
141
+
142
+ # Swap positions with the next lower item, if one exists.
143
+ def move_lower(list_name = :default)
144
+ lower = lower_item
145
+ insert_at_position(list_name, lower.list_position) if lower
146
+ end
147
+ alias_method :move_down, :move_lower
148
+
149
+ # Swap positions with the next higher item, if one exists.
150
+ def move_higher(list_name = :default)
151
+ higher = higher_item
152
+ insert_at_position(list_name, higher.list_position) if higher
153
+ end
154
+ alias_method :move_up, :move_higher
155
+
156
+ # Move to the bottom of the list.
157
+ def move_to_bottom(list_name = :default)
158
+ insert_at_position(list_name, :bottom) if in_list?
159
+ end
160
+
161
+ # Move to the top of the list.
162
+ def move_to_top(list_name = :default)
163
+ insert_at_position(list_name, :top) if in_list?
164
+ end
165
+
166
+ # True if the record is the first in the list.
167
+ def first?(list_name = :default)
168
+ in_list? && list_position == top_position_in_list(list_name)
169
+ end
170
+
171
+ # True if the record is the last in the list.
172
+ def last?(list_name = :default)
173
+ in_list? && list_position == bottom_position_in_list(list_name)
174
+ end
175
+
176
+ # Returns the next higher item in the list.
177
+ def higher_item(list_name = :default)
178
+ return nil unless in_list?
179
+ scoped(list_name).descending(list_name).first(:conditions => options_for_position(list_name, '<'))
180
+ end
181
+ alias_method :previous_item, :higher_item
182
+
183
+ # Returns the next lower item in the list.
184
+ def lower_item(list_name = :default)
185
+ return nil unless in_list?
186
+ scoped(list_name).ascending(list_name).first(:conditions => options_for_position(list_name, '>'))
187
+ end
188
+ alias_method :next_item, :lower_item
189
+
190
+ # True if the record is in the list.
191
+ def in_list?(list_name = :default)
192
+ !list_position(list_name).nil?
193
+ end
194
+
195
+ # Returns the record list position for the list.
196
+ def list_position(list_name = :default)
197
+ send position_column(list_name)
198
+ end
199
+
200
+ # Removes the record from the list and shift other items accordingly.
201
+ def remove_from_list(list_name = :default)
202
+ if in_list?
203
+ acts_as_positionable_class.transaction do
204
+ decrement_positions_on_lower_items(list_name)
205
+ update_attribute position_column(list_name), nil
206
+ end
207
+ end
208
+ end
209
+
210
+ protected
211
+ # Flag the record's position on all lists as long as it meets the lists' conditions.
212
+ # No save or update is performed.
213
+ def add_to_lists
214
+ positionable.lists.each_key do |list_name|
215
+ if !positionable.has_conditions?(list_name) || meet_conditions?(list_name)
216
+ add_to_list_bottom(list_name)
217
+ end
218
+ end
219
+ end
220
+
221
+ # Flag the record's position on a list as after the current last item.
222
+ # No save or update is performed
223
+ def add_to_list_bottom(list_name)
224
+ self[position_column(list_name)] = bottom_position_in_list(list_name) + 1
225
+ end
226
+
227
+ # Remove the record from all lists.
228
+ def remove_from_lists
229
+ positionable.lists.each_key do |list_name|
230
+ remove_from_list(list_name)
231
+ end
232
+ end
233
+
234
+ # Remove and insert the record according to the lists' scopes and conditions.
235
+ def update_lists
236
+ @old_record = acts_as_positionable_class.find self.id
237
+ positionable.lists.each_key do |list_name|
238
+ if positionable.has_scope?(list_name) && scope_changed?(list_name)
239
+ @old_record.remove_from_list(list_name)
240
+ add_to_list_bottom(list_name)
241
+ end
242
+
243
+ if positionable.has_conditions?(list_name) && conditions_changed?(list_name)
244
+ if in_list?(list_name)
245
+ @old_record.remove_from_list(list_name)
246
+ self[position_column(list_name)] = nil
247
+ else
248
+ add_to_list_bottom(list_name)
249
+ end
250
+ end
251
+ end
252
+ end
253
+
254
+ # True if this save action changed the record according to the list's scope.
255
+ def scope_changed?(list_name)
256
+ positionable.scope(list_name).each do |scope|
257
+ return true if @old_record.send(scope) != self.send(scope)
258
+ end
259
+ false
260
+ end
261
+
262
+ # True if this save action changed the record according to the list's conditions.
263
+ def conditions_changed?(list_name)
264
+ @old_record.meet_conditions?(list_name) != self.meet_conditions?(list_name)
265
+ end
266
+
267
+ # True if the record meets the list conditions.
268
+ def meet_conditions?(list_name)
269
+ eval positionable.lists[list_name][:conditions_to_eval]
270
+ end
271
+
272
+ # Returns an activerecord class scope, based on the list's scope and conditions.
273
+ def scoped(list_name)
274
+ chain = acts_as_positionable_class
275
+ if positionable.has_scope?(list_name)
276
+ positionable.scope(list_name).each { |scope| chain = chain.send("scoped_by_#{scope}", send(scope)) }
277
+ end
278
+ chain = chain.send(:conditions, list_name) if positionable.has_conditions?(list_name)
279
+ chain
280
+ end
281
+
282
+ # Returns the position for the first item in list.
283
+ # Lists with gaps might have a number other than 1
284
+ def top_position_in_list(list_name)
285
+ top_item(list_name).try(:list_position, list_name) || 1
286
+ end
287
+ alias_method :first_position_in_list, :top_position_in_list
288
+
289
+ # Returns the first item of the list.
290
+ def top_item(list_name)
291
+ scoped(list_name).ascending(list_name).first(:conditions => options_for_position(list_name, :not_null))
292
+ end
293
+
294
+ # Returns the position for the bottom item in the list.
295
+ def bottom_position_in_list(list_name)
296
+ bottom_item(list_name).try(:list_position, list_name) || 0
297
+ end
298
+ alias_method :last_position_in_list, :bottom_position_in_list
299
+
300
+ # Returns the bottom item.
301
+ def bottom_item(list_name)
302
+ scoped(list_name).descending(list_name).first(:conditions => options_for_position(list_name, :not_null))
303
+ end
304
+
305
+ # Returns the attribute name for the column storing the list position.
306
+ def position_column(list_name = :default)
307
+ positionable.lists[list_name][:column]
308
+ end
309
+
310
+ # Builds position options for updates.
311
+ def options_for_position(list_name, option, value = nil)
312
+ return "#{position_column(list_name)} IS NOT NULL" if option == :not_null
313
+ "#{position_column(list_name)} #{option} #{value || list_position(list_name)}"
314
+ end
315
+
316
+ # Builds position assignment statement for updates.
317
+ def update_options(list_name, sign)
318
+ "#{position_column(list_name)} = (#{position_column(list_name)} #{sign} 1)"
319
+ end
320
+
321
+ # Move all the lower items up one position.
322
+ def decrement_positions_on_lower_items(list_name, limit = nil)
323
+ conditions = options_for_position(list_name, '>')
324
+ conditions << " AND " << options_for_position(list_name, '<=', limit) if limit
325
+ scoped(list_name).update_all(update_options(list_name, '-'), conditions)
326
+ end
327
+
328
+ # Move all items lower than the given position down one position.
329
+ def increment_positions_on_lower_items(list_name, position)
330
+ scoped(list_name).update_all(update_options(list_name, '+'), options_for_position(list_name, '>=', position))
331
+ end
332
+
333
+ # Move all the higher items up one position.
334
+ def increment_positions_on_higher_items(list_name, limit = nil)
335
+ conditions = options_for_position(list_name, '<')
336
+ conditions << " AND " << options_for_position(list_name, '>=', limit) if limit
337
+ scoped(list_name).update_all(update_options(list_name, '+'), conditions)
338
+ end
339
+
340
+ # Insert at the given position and shifts all necessary items accordingly.
341
+ def insert_at_position(list_name, position)
342
+ if position.is_a?(Symbol)
343
+ position = send("#{position}_position_in_list", list_name)
344
+ position = 1 if position == 0
345
+ end
346
+ acts_as_positionable_class.transaction do
347
+ if in_list?
348
+ if position < self.list_position
349
+ increment_positions_on_higher_items(list_name, position)
350
+ elsif position > self.list_position
351
+ decrement_positions_on_lower_items(list_name, position)
352
+ end
353
+ else
354
+ increment_positions_on_lower_items(list_name, position)
355
+ end
356
+ self.update_attribute(position_column(list_name), position)
357
+ end
358
+ end
359
+ end
360
+ end
361
+
362
+ ActiveRecord::Base.extend Positionable::ClassMethods
@@ -0,0 +1,154 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{positionable}
5
+ s.version = "0.2.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Felipe Doria"]
9
+ s.date = %q{2009-07-10}
10
+ s.email = %q{felipe.doria@gmail.com}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.markdown"
14
+ ]
15
+ s.files = [
16
+ ".document",
17
+ ".gitignore",
18
+ "LICENSE",
19
+ "README.markdown",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "app/controllers/positionable_controller.rb",
23
+ "app/helpers/positionable_helper.rb",
24
+ "config/routes.rb",
25
+ "init.rb",
26
+ "lib/positionable.rb",
27
+ "positionable.gemspec",
28
+ "test/rails_root/Rakefile",
29
+ "test/rails_root/app/controllers/application_controller.rb",
30
+ "test/rails_root/app/helpers/application_helper.rb",
31
+ "test/rails_root/app/models/conditional_item.rb",
32
+ "test/rails_root/app/models/different_position_column_item.rb",
33
+ "test/rails_root/app/models/hell_on_earth_item.rb",
34
+ "test/rails_root/app/models/multiple_list_item.rb",
35
+ "test/rails_root/app/models/multiple_scoped_item.rb",
36
+ "test/rails_root/app/models/scoped_item.rb",
37
+ "test/rails_root/app/models/simple_item.rb",
38
+ "test/rails_root/config/boot.rb",
39
+ "test/rails_root/config/database.yml",
40
+ "test/rails_root/config/environment.rb",
41
+ "test/rails_root/config/environments/development.rb",
42
+ "test/rails_root/config/environments/production.rb",
43
+ "test/rails_root/config/environments/test.rb",
44
+ "test/rails_root/config/initializers/backtrace_silencers.rb",
45
+ "test/rails_root/config/initializers/inflections.rb",
46
+ "test/rails_root/config/initializers/mime_types.rb",
47
+ "test/rails_root/config/initializers/new_rails_defaults.rb",
48
+ "test/rails_root/config/initializers/session_store.rb",
49
+ "test/rails_root/config/locales/en.yml",
50
+ "test/rails_root/config/routes.rb",
51
+ "test/rails_root/db/development.sqlite3",
52
+ "test/rails_root/db/migrate/20090702170207_create_simple_items.rb",
53
+ "test/rails_root/db/migrate/20090703071830_create_scoped_items.rb",
54
+ "test/rails_root/db/migrate/20090706180046_create_different_position_column_items.rb",
55
+ "test/rails_root/db/migrate/20090706200318_create_conditional_items.rb",
56
+ "test/rails_root/db/migrate/20090708045618_create_multiple_scoped_items.rb",
57
+ "test/rails_root/db/migrate/20090708174947_create_multiple_list_items.rb",
58
+ "test/rails_root/db/migrate/20090708183550_create_hell_on_earth_items.rb",
59
+ "test/rails_root/db/schema.rb",
60
+ "test/rails_root/script/about",
61
+ "test/rails_root/script/console",
62
+ "test/rails_root/script/dbconsole",
63
+ "test/rails_root/script/destroy",
64
+ "test/rails_root/script/generate",
65
+ "test/rails_root/script/performance/benchmarker",
66
+ "test/rails_root/script/performance/profiler",
67
+ "test/rails_root/script/plugin",
68
+ "test/rails_root/script/runner",
69
+ "test/rails_root/script/server",
70
+ "test/rails_root/test/conditional_tests.rb",
71
+ "test/rails_root/test/functional/positionable_controller_test.rb",
72
+ "test/rails_root/test/performance/browsing_test.rb",
73
+ "test/rails_root/test/scoped_tests.rb",
74
+ "test/rails_root/test/simple_gap_tests.rb",
75
+ "test/rails_root/test/simple_gapless_tests.rb",
76
+ "test/rails_root/test/simple_tests.rb",
77
+ "test/rails_root/test/test_helper.rb",
78
+ "test/rails_root/test/unit/conditional_item_test.rb",
79
+ "test/rails_root/test/unit/different_position_column_item_test.rb",
80
+ "test/rails_root/test/unit/eval_support_test.rb",
81
+ "test/rails_root/test/unit/hell_on_earth_item_test.rb",
82
+ "test/rails_root/test/unit/helpers/positionable_helper_test.rb",
83
+ "test/rails_root/test/unit/multiple_list_item_test.rb",
84
+ "test/rails_root/test/unit/multiple_scoped_item_test.rb",
85
+ "test/rails_root/test/unit/scoped_item_test.rb",
86
+ "test/rails_root/test/unit/scoped_item_with_gaps_test.rb",
87
+ "test/rails_root/test/unit/simple_item_test.rb",
88
+ "test/rails_root/test/unit/simple_item_with_gaps_test.rb"
89
+ ]
90
+ s.homepage = %q{http://github.com/aguids/positionable}
91
+ s.rdoc_options = ["--charset=UTF-8"]
92
+ s.require_paths = ["lib"]
93
+ s.rubygems_version = %q{1.3.4}
94
+ s.summary = %q{acts-as-list extension stretched to controllers and helpers}
95
+ s.test_files = [
96
+ "test/rails_root/app/controllers/application_controller.rb",
97
+ "test/rails_root/app/helpers/application_helper.rb",
98
+ "test/rails_root/app/models/conditional_item.rb",
99
+ "test/rails_root/app/models/different_position_column_item.rb",
100
+ "test/rails_root/app/models/hell_on_earth_item.rb",
101
+ "test/rails_root/app/models/multiple_list_item.rb",
102
+ "test/rails_root/app/models/multiple_scoped_item.rb",
103
+ "test/rails_root/app/models/scoped_item.rb",
104
+ "test/rails_root/app/models/simple_item.rb",
105
+ "test/rails_root/config/boot.rb",
106
+ "test/rails_root/config/environment.rb",
107
+ "test/rails_root/config/environments/development.rb",
108
+ "test/rails_root/config/environments/production.rb",
109
+ "test/rails_root/config/environments/test.rb",
110
+ "test/rails_root/config/initializers/backtrace_silencers.rb",
111
+ "test/rails_root/config/initializers/inflections.rb",
112
+ "test/rails_root/config/initializers/mime_types.rb",
113
+ "test/rails_root/config/initializers/new_rails_defaults.rb",
114
+ "test/rails_root/config/initializers/session_store.rb",
115
+ "test/rails_root/config/routes.rb",
116
+ "test/rails_root/db/migrate/20090702170207_create_simple_items.rb",
117
+ "test/rails_root/db/migrate/20090703071830_create_scoped_items.rb",
118
+ "test/rails_root/db/migrate/20090706180046_create_different_position_column_items.rb",
119
+ "test/rails_root/db/migrate/20090706200318_create_conditional_items.rb",
120
+ "test/rails_root/db/migrate/20090708045618_create_multiple_scoped_items.rb",
121
+ "test/rails_root/db/migrate/20090708174947_create_multiple_list_items.rb",
122
+ "test/rails_root/db/migrate/20090708183550_create_hell_on_earth_items.rb",
123
+ "test/rails_root/db/schema.rb",
124
+ "test/rails_root/test/conditional_tests.rb",
125
+ "test/rails_root/test/functional/positionable_controller_test.rb",
126
+ "test/rails_root/test/performance/browsing_test.rb",
127
+ "test/rails_root/test/scoped_tests.rb",
128
+ "test/rails_root/test/simple_gap_tests.rb",
129
+ "test/rails_root/test/simple_gapless_tests.rb",
130
+ "test/rails_root/test/simple_tests.rb",
131
+ "test/rails_root/test/test_helper.rb",
132
+ "test/rails_root/test/unit/conditional_item_test.rb",
133
+ "test/rails_root/test/unit/different_position_column_item_test.rb",
134
+ "test/rails_root/test/unit/eval_support_test.rb",
135
+ "test/rails_root/test/unit/hell_on_earth_item_test.rb",
136
+ "test/rails_root/test/unit/helpers/positionable_helper_test.rb",
137
+ "test/rails_root/test/unit/multiple_list_item_test.rb",
138
+ "test/rails_root/test/unit/multiple_scoped_item_test.rb",
139
+ "test/rails_root/test/unit/scoped_item_test.rb",
140
+ "test/rails_root/test/unit/scoped_item_with_gaps_test.rb",
141
+ "test/rails_root/test/unit/simple_item_test.rb",
142
+ "test/rails_root/test/unit/simple_item_with_gaps_test.rb"
143
+ ]
144
+
145
+ if s.respond_to? :specification_version then
146
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
147
+ s.specification_version = 3
148
+
149
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
150
+ else
151
+ end
152
+ else
153
+ end
154
+ end
@@ -0,0 +1,10 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require(File.join(File.dirname(__FILE__), 'config', 'boot'))
5
+
6
+ require 'rake'
7
+ require 'rake/testtask'
8
+ require 'rake/rdoctask'
9
+
10
+ require 'tasks/rails'
@@ -0,0 +1,10 @@
1
+ # Filters added to this controller apply to all controllers in the application.
2
+ # Likewise, all the methods added will be available for all controllers.
3
+
4
+ class ApplicationController < ActionController::Base
5
+ helper :all # include all helpers, all the time
6
+ protect_from_forgery # See ActionController::RequestForgeryProtection for details
7
+
8
+ # Scrub sensitive parameters from your log
9
+ # filter_parameter_logging :password
10
+ end
@@ -0,0 +1,3 @@
1
+ # Methods added to this helper will be available to all templates in the application.
2
+ module ApplicationHelper
3
+ end
@@ -0,0 +1,3 @@
1
+ class ConditionalItem < ActiveRecord::Base
2
+ acts_as_positionable :conditions => {:tag => 'todo'}
3
+ end
@@ -0,0 +1,3 @@
1
+ class DifferentPositionColumnItem < ActiveRecord::Base
2
+ acts_as_positionable :column => :different_position
3
+ end
@@ -0,0 +1,5 @@
1
+ class HellOnEarthItem < ActiveRecord::Base
2
+ acts_as_positionable :scope => [:parent_id, :session_id], :conditions => {:published => true}
3
+ acts_as_positionable :list_name => :client, :column => "client_position", :scope => :parent_id, :conditions => {:published => false}
4
+ acts_as_positionable :list_name => :developer, :column => "developer_position", :scope => :parent_id, :conditions => {:published => false, :tag => 'todo'}
5
+ end
@@ -0,0 +1,5 @@
1
+ class MultipleListItem < ActiveRecord::Base
2
+ acts_as_positionable
3
+ acts_as_positionable :list_name => :client, :column => "client_position"
4
+ acts_as_positionable :list_name => :developer, :column => "developer_position"
5
+ end
@@ -0,0 +1,3 @@
1
+ class MultipleScopedItem < ActiveRecord::Base
2
+ acts_as_positionable :scope => [:parent_id, :tag]
3
+ end
@@ -0,0 +1,3 @@
1
+ class ScopedItem < ActiveRecord::Base
2
+ acts_as_positionable :scope => :parent_id
3
+ end
@@ -0,0 +1,4 @@
1
+ # Simple list. No scoping, no conditions, default position column.
2
+ class SimpleItem < ActiveRecord::Base
3
+ acts_as_positionable
4
+ end