lib/sequel/plugins/list.rb in sequel-5.9.0 vs lib/sequel/plugins/list.rb in sequel-5.10.0

- old
+ new

@@ -43,23 +43,30 @@ # Note that using this plugin modifies the order of the model's dataset to # sort by the position and scope fields. Also note that this plugin is subject to # race conditions, and is not safe when concurrent modifications are made # to the same list. # - # Additionally, note that unlike ruby arrays, the list plugin assumes that the - # first entry in the list has position 1, not position 0. + # Note that by default, unlike ruby arrays, the list plugin assumes the first + # entry in the list has position 1, not position 0. # + # You can change this by providing an integer <tt>:top</tt> option: + # + # Item.plugin :list, top: 0 + # # Copyright (c) 2007-2010 Sharon Rosner, Wayne E. Seguin, Aman Gupta, Adrian Madrid, Jeremy Evans module List - # Set the +position_field+ and +scope_proc+ attributes for the model, - # using the <tt>:field</tt> and <tt>:scope</tt> options, respectively. + # Set the +position_field+, +scope_proc+ and +top_of_list+ attributes for the model, + # using the <tt>:field</tt>, <tt>:scope</tt>, and <tt>:top</tt> options, respectively. # The <tt>:scope</tt> option can be a symbol, array of symbols, or a proc that # accepts a model instance and returns a dataset representing the list. # Also, modify the model dataset's order to order by the position and scope fields. def self.configure(model, opts = OPTS) model.position_field = opts[:field] || :position model.dataset = model.dataset.order_prepend(model.position_field) + model.instance_exec do + @top_of_list = opts[:top] || 1 + end model.scope_proc = case scope = opts[:scope] when Symbol model.dataset = model.dataset.order_prepend(scope) proc{|obj| obj.model.where(scope=>obj.public_send(scope))} @@ -78,11 +85,14 @@ # A proc that scopes the dataset, so that there can be multiple positions # in the list, but the positions are unique with the scoped dataset. This # proc should accept an instance and return a dataset representing the list. attr_accessor :scope_proc - Plugins.inherited_instance_variables(self, :@position_field=>nil, :@scope_proc=>nil) + # An Integer to use as the position of the top of the list. Defaults to 1. + attr_reader :top_of_list + + Plugins.inherited_instance_variables(self, :@position_field=>nil, :@scope_proc=>nil, :@top_of_list=>nil) end module InstanceMethods # The model object at the given position in the list containing this instance. def at_position(p) @@ -120,11 +130,11 @@ current = position_value if target != current checked_transaction do ds = list_dataset op, ds = if target < current - target = 1 if target < 1 + target = model.top_of_list if target < model.top_of_list [:+, ds.where(position_field=>target...current)] else lp ||= last_position target = lp if target > lp [:-, ds.where(position_field=>(current + 1)..target)] @@ -140,12 +150,12 @@ def move_to_bottom lp = last_position move_to(lp, lp) end - # Move this instance to the top (first position, position 1) of the list. + # Move this instance to the top (first position, usually position 1) of the list. def move_to_top - move_to(1) + move_to(model.top_of_list) end # Move this instance the given number of places up in the list, or 1 place # if no argument is specified. def move_up(n = 1)