{"id":26197312,"url":"https://github.com/mongoid/mongoid_orderable","last_synced_at":"2025-04-15T03:55:40.205Z","repository":{"id":1834106,"uuid":"2758440","full_name":"mongoid/mongoid_orderable","owner":"mongoid","description":"Acts as list mongoid implementation","archived":false,"fork":false,"pushed_at":"2023-11-07T18:04:39.000Z","size":217,"stargazers_count":103,"open_issues_count":3,"forks_count":43,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-15T03:55:35.150Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"scrapy/scrapy","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mongoid.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2011-11-11T20:45:35.000Z","updated_at":"2023-03-08T10:24:18.000Z","dependencies_parsed_at":"2023-02-17T23:01:20.478Z","dependency_job_id":"33660b66-7784-46d4-bf27-fce2c6995d98","html_url":"https://github.com/mongoid/mongoid_orderable","commit_stats":{"total_commits":120,"total_committers":19,"mean_commits":6.315789473684211,"dds":0.7666666666666666,"last_synced_commit":"d2d47c7a3ba9a393d24bb5806356712aa09677ca"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongoid%2Fmongoid_orderable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongoid%2Fmongoid_orderable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongoid%2Fmongoid_orderable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongoid%2Fmongoid_orderable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mongoid","download_url":"https://codeload.github.com/mongoid/mongoid_orderable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249003952,"owners_count":21196794,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-12T02:26:00.824Z","updated_at":"2025-04-15T03:55:40.189Z","avatar_url":"https://github.com/mongoid.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Gem Version](https://badge.fury.io/rb/mongoid_orderable.svg)](https://badge.fury.io/rb/mongoid_orderable)\n[![Build Status](https://travis-ci.org/mongoid/mongoid_orderable.svg?branch=master)](https://travis-ci.org/mongoid/mongoid_orderable)\n\n# Mongoid Orderable\n\nMongoid::Orderable is a ordered list implementation for your Mongoid 7+ projects.\n\n### Core Features\n\n* Sets a position index field on your documents which allows you to sort them in order.\n* Uses MongoDB's `$inc` operator to batch-update position.\n* Supports scope for position index, including changing scopes.\n* Supports multiple position indexes on the same document.\n* (Optional) Uses [MongoDB transactions](https://docs.mongodb.com/manual/core/transactions/) to ensure order integrity during concurrent updates.\n\n### Version Support\n\nAs of version 6.0.0, Mongoid::Orderable supports the following dependency versions:\n\n* Ruby 2.6+\n* Mongoid 7.0+\n* Rails 5.2+\n\nFor older versions, please use Mongoid::Orderable 5.x and earlier.\n\nTransaction support requires MongoDB 4.2+ (4.4+ recommended.)\n\n## Usage\n\n### Getting Started\n\n```ruby\ngem 'mongoid_orderable'\n```\n\nInclude `Mongoid::Orderable` into your model and call `orderable` method.\nEmbedded objects are automatically scoped to their parent.\n\n```ruby\nclass MyModel\n  include Mongoid::Document\n  include Mongoid::Orderable\n\n  belongs_to :group\n  belongs_to :drawer, class_name: \"Office::Drawer\",\n             foreign_key: \"legacy_drawer_key_id\"\n\n  orderable\n\n  # if you set :scope as a symbol, it will resolve the foreign key from relation\n  orderable scope: :drawer, field: :pos\n\n  # if you set :scope as a string, it will use it as the field name for scope\n  orderable scope: 'drawer', field: :pos\n\n  # scope can also be a proc\n  orderable scope: -\u003e(doc) { where(group_id: doc.group_id) }\n\n  # this one if you want specify indexes manually\n  orderable index: false \n\n  # count position from zero as the top-most value (1 is the default value)\n  orderable base: 0\nend\n```\n\nYou can also set default config values in an initializer, which will be\napplied when calling the `orderable` macro in a model.\n\n```ruby\n# configs/initializers/mongoid_orderable.rb\nMongoid::Orderable.configure do |config|\n  config.field = :pos\n  config.base = 0\n  config.index = false\nend\n```\n\n### Moving Position\n\n```ruby\nitem.move_to 2 # just change position\nitem.move_to! 2 # and save\nitem.move_to = 2 # assignable method\n\n# symbol position\nitem.move_to :top\nitem.move_to :bottom\nitem.move_to :higher\nitem.move_to :lower\n\n# generated methods\nitem.move_to_top\nitem.move_to_bottom\nitem.move_higher\nitem.move_lower\n\nitem.next_items # return a collection of items higher on the list\nitem.previous_items # return a collection of items lower on the list\n\nitem.next_item # returns the next item in the list\nitem.previous_item # returns the previous item in the list\n```\n\n### Multiple Fields\n\nYou can also define multiple orderable fields for any class including the Mongoid::Orderable module.\n\n```ruby\nclass Book\n  include Mongoid::Document\n  include Mongoid::Orderable\n\n  orderable base: 0\n  orderable field: sno, as: :serial_no\nend\n```\n\nThe above defines two different orderable_fields on Book - *position* and *serial_no*.\nThe following helpers are generated in this case:\n\n```ruby\nbook.move_#{field}_to\nbook.move_#{field}_to=\nbook.move_#{field}_to!\n\nbook.move_#{field}_to_top\nbook.move_#{field}_to_bottom\nbook.move_#{field}_higher\nbook.move_#{field}_lower\n\nbook.next_#{field}_items\nbook.previous_#{field}_items\n\nbook.next_#{field}_item\nbook.previous_#{field}_item\n```\n\nwhere `#{field}` is either `position` or `serial_no`.\n\nWhen a model defines multiple orderable fields, the original helpers are also available and work\non the first orderable field.\n\n```ruby\n  @book1 = Book.create!\n  @book2 = Book.create!\n  @book2                 # =\u003e \u003cBook _id: 53a16a2ba1bde4f746000001, serial_no: 1, position: 1\u003e\n  @book2.move_to! :top   # this will change the :position of the book to 0 (not serial_no)\n  @book2                 # =\u003e \u003cBook _id: 53a16a2ba1bde4f746000001, serial_no: 1, position: 0\u003e\n```\n\nTo specify any other orderable field as default pass the **default: true** option with orderable.\n\n```ruby\n  orderable field: sno, as: :serial_no, default: true\n```\n\n### Embedded Documents\n\n```ruby\nclass Question\n  include Mongoid::Document\n  include Mongoid::Orderable\n\n  embedded_in :survey\n\n  orderable\nend\n```\n\nIf you bulk import embedded documents without specifying their position,\nno field `position` will be written.\n\n```ruby\nclass Survey\n  include Mongoid::Document\n\n  embeds_many :questions, cascade_callbacks: true\nend\n```\n\nTo ensure the position is written correctly, you will need to set\n`cascade_callbacks: true` on the relation.\n\n### Disable Ordering\n\nYou can disable position tracking for specific documents using the `:if` and `:unless` options.\nThis is in advanced scenarios where you want to control position manually for certain documents.\nIn general, the disable condition should match a specific scope.\n**Warning:** If used improperly, this will cause your documents to become out-of-order.\n\n```ruby\nclass Book\n  include Mongoid::Document\n  include Mongoid::Orderable\n\n  field :track_position, type: Boolean\n  \n  orderable if: :track_position, unless: -\u003e { created_at \u003c Date.parse('2020-01-01') }\nend\n```\n\n## Transaction Support\n\nBy default, Mongoid Orderable does not guarantee ordering consistency\nwhen doing multiple concurrent updates on documents. This means that\ninstead of having positions `1, 2, 3, 4, 5`, after running your system\nin production at scale your position data will become corrupted, e.g.\n`1, 1, 4, 4, 6`. To remedy this, this Mongoid Orderable can use\n[MongoDB transactions](https://docs.mongodb.com/manual/core/transactions/)\n\n### Prerequisites\n\n* MongoDB version 4.2+ (4.4+ recommended.)\n* Requires [MongoDB Replica Set](https://docs.mongodb.com/manual/tutorial/deploy-replica-set/) topology\n\n### Configuration\n\nYou may enable transactions on both the global and model configs:\n\n```ruby\nMongoid::Orderable.configure do |config|\n  config.use_transactions = true       # default: false\n  config.transaction_max_retries = 10  # default: 10\nend\n\nclass MyModel\n  orderable :position, use_transactions: false\nend\n```\n\nWhen two transactions are attempted at the same time, database-level\n`WriteConflict` failures may result and retries will be attempted.\nAfter `transaction_max_retries` has been exceeded, a\n`Mongoid::Orderable::Errors::TransactionFailed` error will be raised.\n\n### Locks\n\nWhen using transactions, Mongoid Orderable creates a collection\n`mongoid_orderable_locks` which is used to store temporary lock objects.\nLock collections use a TTL index which auto-deletes objects older than 1 day.\n\nYou can change the lock collection name globally or per model:\n\n```ruby\nMongoid::Orderable.configure do |config|\n  config.lock_collection = \"my_locks\"  # default: \"mongoid_orderable_locks\"\nend\n\nclass MyModel\n  orderable :position, lock_collection: \"my_model_locks\"\nend\n```\n\n### MongoDB 4.2 Support\n\nIn MongoDB 4.2, collections cannot be created within transactions.\nTherefore, you will need to manually run the following command once\nto initialize the lock collection:\n\n```ruby\nMongoid::Orderable::Models::Lock.create!\n```\n\nThis step is not necessary when using MongoDB 4.4+.\n\n### Contributing\n\nPlease fork the project on Github and raise a pull request including passing specs.\n\n### Copyright \u0026 License\n\nCopyright (c) 2011 Arkadiy Zabazhanov, Johnny Shields, and contributors.\n\nMIT license, see [LICENSE](LICENSE.txt) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmongoid%2Fmongoid_orderable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmongoid%2Fmongoid_orderable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmongoid%2Fmongoid_orderable/lists"}