{"id":19474557,"url":"https://github.com/tomasc/mongoid_occurrences","last_synced_at":"2026-05-16T15:05:49.092Z","repository":{"id":56884369,"uuid":"145094649","full_name":"tomasc/mongoid_occurrences","owner":"tomasc","description":"Facilitates aggregations for events with multiple occurrences or a recurring schedule.","archived":false,"fork":false,"pushed_at":"2025-02-05T10:01:02.000Z","size":167,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-05-01T07:09:16.897Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomasc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-17T08:36:07.000Z","updated_at":"2025-02-05T09:45:15.000Z","dependencies_parsed_at":"2022-08-20T23:40:35.929Z","dependency_job_id":null,"html_url":"https://github.com/tomasc/mongoid_occurrences","commit_stats":null,"previous_names":["tomasc/mongoid_occurrence_views"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/tomasc/mongoid_occurrences","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomasc%2Fmongoid_occurrences","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomasc%2Fmongoid_occurrences/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomasc%2Fmongoid_occurrences/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomasc%2Fmongoid_occurrences/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomasc","download_url":"https://codeload.github.com/tomasc/mongoid_occurrences/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomasc%2Fmongoid_occurrences/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33107571,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T04:41:52.686Z","status":"ssl_error","status_checked_at":"2026-05-16T04:41:52.009Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":"2024-11-10T19:25:38.068Z","updated_at":"2026-05-16T15:05:49.052Z","avatar_url":"https://github.com/tomasc.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mongoid Occurrences\n\n[![Build Status](https://travis-ci.org/tomasc/mongoid_occurrences.svg)](https://travis-ci.org/tomasc/mongoid_occurrences) [![Gem Version](https://badge.fury.io/rb/mongoid_occurrences.svg)](http://badge.fury.io/rb/mongoid_occurrences) [![Coverage Status](https://img.shields.io/coveralls/tomasc/mongoid_occurrences.svg)](https://coveralls.io/r/tomasc/mongoid_occurrences)\n\nFacilitates aggregations for events with multiple occurrences or a recurring schedule.\n\n## Requirements\n\n* Mongoid 7+\n* MongoDB 3.4+\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'mongoid_occurrences'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install mongoid_occurrences\n\n## Usage\n\n### Event\n\nDefine a Mongoid document that will embed occurrence definitions.\n\n```ruby\nclass Event\n  include Mongoid::Document\n  include MongoidOccurrences::HasOccurrences\n\n  embeds_many_occurrences class_name: \"Occurrence\"\nend\n```\n\nThis document will gain the `#assign_daily_occurrences!` method (automatically triggered `:after_validation`), which expands all occurrence definitions in the embedded relation called `#daily_occurrences`.\n\nThe class will also gain the following scopes, useful for querying for events based on the `#daily_occurrences`:\n\n* `.occurs_between(dtstart, dtend)`\n* `.occurs_from(dtstart)`\n* `.occurs_on(day)`\n* `.occurs_until(dtend)`\n\n### Occurrence\n\nDefine a Mongoid document that defines the occurrence.\n\n```ruby\nclass Occurrence\n  include Mongoid::Document\n  include MongoidOccurrences::Occurrence\n\n  embedded_in_event :event, class_name: 'Event'\nend\n```\n\nThis document will gain the `#dtstart`, `#dtend` and `#all_day` fields to define individual occurrences.\n\nRecurring schedule is handled via the [IceCube](https://github.com/seejohnrun/ice_cube) and [MongoidIceCubeExtension](https://github.com/tomasc/mongoid_ice_cube_extension) gems. The model gains `#schedule`, and `#schedule_dtstart`, `#schedule_dtend` fields (with default values for schedule 1 year from now), along with `#recurrence_rule=` writer method.\n\nIt is possible to influence the way the occurrences are expanded into `#daily_occurrences` using the `#operator` enum field, which accepts the following values:\n\n* `:append` – appends to the list of `#daily_occurrences` (default)\n* `:replace` – replaces all occurrences that happen on the same day with itself\n* `:remove` - removes all occurrences that happen on the same day\n\n### Indexes\n\nTo optimize the performance of the above scope queries, you might want to add the following indexes:\n\n```ruby\nindex :'daily_occurrences.ds' =\u003e 1\nindex :'daily_occurrences.de' =\u003e 1\n```\n\n### Aggregations\n\nIt is possible to aggregate (unwind) the events so that they are multiplied per daily occurrences. Example aggregations are included:\n\n* `MongoidOccurrences::Aggregations::OccursBetween.instantiate(Event.criteria, dtstart, dtend)`\n* `MongoidOccurrences::Aggregations::OccursFrom.instantiate(Event.criteria, dtstart)`\n* `MongoidOccurrences::Aggregations::OccursOn.instantiate(Event.criteria, day)`\n* `MongoidOccurrences::Aggregations::OccursUntil.instantiate(Event.criteria, dtend)`\n\nThe aggregations will add `#_dtstart`, `#_dtend` fields to the unwound documents. For easier access, mixin the `MongoidOccurrences::HasFieldsFromAggregation` to your `Event` class:\n\n```ruby\nclass Event\n  include Mongoid::Document\n  include MongoidOccurrences::HasFieldsFromAggregation\n  include MongoidOccurrences::HasOccurrences\n\n  embeds_many_occurrences class_name: \"Occurrence\"\nend\n```\n\nThis will automatically add `#dtstart` and `#dtend` fields with correct (demongoized) values, as well as the `#all_day?` method.\n\n### Embedded events\n\nIf your events are itself embedded:\n\n```ruby\nclass EventParent\n  embeds_many :events, class_name: 'Event'\nend\n```\n\nSimply add the following scopes on the parent document:\n\n```ruby\nclass EventParent\n  scope :occurs_between, -\u003e(dtstart, dtend) { elem_match(events: Event.occurs_between(dtstart, dtend).selector) }\n  scope :occurs_from, -\u003e(date_time) { elem_match(events: Event.occurs_from(date_time).selector) }\n  scope :occurs_on, -\u003e(date_time) { elem_match(events: Event.occurs_on(date_time).selector) }\n  scope :occurs_until, -\u003e(date_time) { elem_match(events: Event.occurs_until(date_time).selector) }\n\n  include MongoidOccurrences::HasFieldsFromAggregation\n\n  delegate :daily_occurrences, to: :event\nend\n```\n\nYou will then need to write your own aggregations with an extra step to `$unwind` the embedded `#events`, and your indexes will need to be adjusted as follows:\n\n```ruby\nindex :'events.daily_occurrences.ds' =\u003e 1\nindex :'events.daily_occurrences.de' =\u003e 1\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/tomasc/mongoid_occurrences.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomasc%2Fmongoid_occurrences","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomasc%2Fmongoid_occurrences","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomasc%2Fmongoid_occurrences/lists"}