aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/mixins/list.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2004-12-16 02:49:18 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2004-12-16 02:49:18 +0000
commit1f916a119ca5c61174cb58124ea989c1e8b00fd4 (patch)
treea21bc3c8990c5fb6364ff04cc1b3bcd59a8ba27e /activerecord/lib/active_record/mixins/list.rb
parent8bc82278dddfe23d84ac24ffe83f92c816028dd8 (diff)
downloadrails-1f916a119ca5c61174cb58124ea989c1e8b00fd4.tar.gz
rails-1f916a119ca5c61174cb58124ea989c1e8b00fd4.tar.bz2
rails-1f916a119ca5c61174cb58124ea989c1e8b00fd4.zip
Added that Active Records will automatically record creation and/or update timestamps of database objects if fields of the names created_at/created_on or updated_at/updated_on are present. [Tobias Luetke] Added acts_as_tree that can decorates an existing class with a many to many relationship with itself. Added acts_as_list that can decorates an existing class with methods like move_higher/lower, move_to_top/bottom.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@176 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record/mixins/list.rb')
-rw-r--r--activerecord/lib/active_record/mixins/list.rb221
1 files changed, 118 insertions, 103 deletions
diff --git a/activerecord/lib/active_record/mixins/list.rb b/activerecord/lib/active_record/mixins/list.rb
index bec4b33651..16a60d7b6c 100644
--- a/activerecord/lib/active_record/mixins/list.rb
+++ b/activerecord/lib/active_record/mixins/list.rb
@@ -28,141 +28,156 @@ module ActiveRecord
# todo_list.last.move_higher
module List
def self.append_features(base)
- super
- base.before_destroy :remove_from_list
- base.after_create :add_to_list_bottom
+ super
+ base.extend(ClassMethods)
end
- # can be overriden
-
- def position_column
- "position"
- end
+ module ClassMethods
+ def acts_as_list(options = {})
+ configuration = { :column => "position", :scope => "1" }
+ configuration.update(options) if options.is_a?(Hash)
+
+ class_eval <<-EOV
+ include InstanceMethods
- # Moving around on the list
+ def position_column
+ '#{configuration[:column]}'
+ end
- def move_lower
- return unless lower_item
-
- self.class.transaction do
- lower_item.decrement_position
- increment_position
+ def scope_condition
+ "#{configuration[:scope]} = \#{#{configuration[:scope]}}"
+ end
+
+ before_destroy :remove_from_list
+ after_create :add_to_list_bottom
+ EOV
end
- end
+
+ module InstanceMethods
+ def move_lower
+ return unless lower_item
- def move_higher
- return unless higher_item
+ self.class.transaction do
+ lower_item.decrement_position
+ increment_position
+ end
+ end
- self.class.transaction do
- higher_item.increment_position
- decrement_position
- end
- end
+ def move_higher
+ return unless higher_item
+
+ self.class.transaction do
+ higher_item.increment_position
+ decrement_position
+ end
+ end
- def move_to_bottom
- self.class.transaction do
- decrement_positions_on_lower_items
- assume_bottom_position
- end
- end
+ def move_to_bottom
+ self.class.transaction do
+ decrement_positions_on_lower_items
+ assume_bottom_position
+ end
+ end
- def move_to_top
- self.class.transaction do
- increment_positions_on_higher_items
- assume_top_position
- end
- end
+ def move_to_top
+ self.class.transaction do
+ increment_positions_on_higher_items
+ assume_top_position
+ end
+ end
- # Entering or existing the list
+ # Entering or existing the list
- def add_to_list_top
- increment_positions_on_all_items
- end
+ def add_to_list_top
+ increment_positions_on_all_items
+ end
- def add_to_list_bottom
- assume_bottom_position
- end
+ def add_to_list_bottom
+ assume_bottom_position
+ end
- def remove_from_list
- decrement_positions_on_lower_items
- end
+ def remove_from_list
+ decrement_positions_on_lower_items
+ end
- # Changing the position
+ # Changing the position
- def increment_position
- update_attribute position_column, self.send(position_column).to_i + 1
- end
+ def increment_position
+ update_attribute position_column, self.send(position_column).to_i + 1
+ end
- def decrement_position
- update_attribute position_column, self.send(position_column).to_i - 1
- end
+ def decrement_position
+ update_attribute position_column, self.send(position_column).to_i - 1
+ end
- # Querying the position
+ # Querying the position
- def first?
- self.send(position_column) == 1
- end
+ def first?
+ self.send(position_column) == 1
+ end
- def last?
- self.send(position_column) == bottom_position_in_list
- end
+ def last?
+ self.send(position_column) == bottom_position_in_list
+ end
- private
- # Overwrite this method to define the scope of the list changes
- def scope_condition() "1" end
+ private
+ # Overwrite this method to define the scope of the list changes
+ def scope_condition() "1" end
- def higher_item
- self.class.find_first(
- "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}"
- )
- end
+ def higher_item
+ self.class.find_first(
+ "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}"
+ )
+ end
- def lower_item
- self.class.find_first(
- "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}"
- )
- end
+ def lower_item
+ self.class.find_first(
+ "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}"
+ )
+ end
- def bottom_position_in_list
- item = bottom_item
- item ? item.send(position_column) : 0
- end
+ def bottom_position_in_list
+ item = bottom_item
+ item ? item.send(position_column) : 0
+ end
- def bottom_item
- self.class.find_first(
- "#{scope_condition} ",
- "#{position_column} DESC"
- )
- end
+ def bottom_item
+ self.class.find_first(
+ "#{scope_condition} ",
+ "#{position_column} DESC"
+ )
+ end
- def assume_bottom_position
- update_attribute position_column, bottom_position_in_list.to_i + 1
- end
+ def assume_bottom_position
+ update_attribute position_column, bottom_position_in_list.to_i + 1
+ end
- def assume_top_position
- update_attribute position_column, 1
- end
+ def assume_top_position
+ update_attribute position_column, 1
+ end
- def decrement_positions_on_lower_items
- self.class.update_all(
- "#{position_column} = (#{position_column} - 1)", "#{scope_condition} AND #{position_column} > #{send(position_column).to_i}"
- )
- end
+ def decrement_positions_on_lower_items
+ self.class.update_all(
+ "#{position_column} = (#{position_column} - 1)", "#{scope_condition} AND #{position_column} > #{send(position_column).to_i}"
+ )
+ end
- def increment_positions_on_higher_items
- self.class.update_all(
- "#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} < #{send(position_column)}"
- )
- end
+ def increment_positions_on_higher_items
+ self.class.update_all(
+ "#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} < #{send(position_column)}"
+ )
+ end
- def increment_positions_on_all_items
- self.class.update_all(
- "#{position_column} = (#{position_column} + 1)", "#{scope_condition}"
- )
- end
+ def increment_positions_on_all_items
+ self.class.update_all(
+ "#{position_column} = (#{position_column} + 1)", "#{scope_condition}"
+ )
+ end
+ end
+ end
end
end
end \ No newline at end of file