aguids-positionable 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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