The list plugin allows for model instances to be part of an ordered list, based on a position field in the database. It can either consider all rows in the table as being from the same list, or you can specify scopes so that multiple lists can be kept in the same table.
Basic Example:
class Item < Sequel::Model(:items) plugin :list # will use :position field for position plugin :list, field: :pos # will use :pos field for position end item = Item[1] # Get the next or previous item in the list item.next item.prev # Modify the item's position, which may require modifying other items in # the same list item.move_to(3) item.move_to_top item.move_to_bottom item.move_up item.move_down
You can provide a :scope
option to scope the list. This option can be a symbol or array of symbols specifying column name(s), or a proc that accepts a model instance and returns a dataset representing the list the object is in. You will need to provide a :scope
option if the model’s dataset uses a subquery (such as when using the class_table_inheritance plugin).
For example, if each item has a user_id
field, and you want every user to have their own list:
Item.plugin :list, scope: :user_id
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.
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 :top
option:
Item.plugin :list, top: 0
Copyright © 2007-2010 Sharon Rosner, Wayne E. Seguin, Aman Gupta, Adrian Madrid, Jeremy Evans
Classes and Modules
Public Class methods
Set the position_field
, scope_proc
and top_of_list
attributes for the model, using the :field
, :scope
, and :top
options, respectively. The :scope
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.
# File lib/sequel/plugins/list.rb 64 def self.configure(model, opts = OPTS) 65 model.position_field = opts[:field] || :position 66 model.dataset = model.dataset.order_prepend(model.position_field) 67 model.instance_exec do 68 @top_of_list = opts[:top] || 1 69 end 70 71 model.scope_proc = case scope = opts[:scope] 72 when Symbol 73 model.dataset = model.dataset.order_prepend(scope) 74 proc{|obj| obj.model.where(scope=>obj.public_send(scope))} 75 when Array 76 model.dataset = model.dataset.order_prepend(*scope) 77 proc{|obj| obj.model.where(scope.map{|s| [s, obj.get_column_value(s)]})} 78 else 79 scope 80 end 81 end