{"id":17682194,"url":"https://github.com/emancu/ector-multi","last_synced_at":"2025-06-12T17:34:03.891Z","repository":{"id":62557764,"uuid":"162998674","full_name":"emancu/ector-multi","owner":"emancu","description":"`Ector::Multi` is an object for grouping multiple DB operations that should be performed in a single database transaction.","archived":false,"fork":false,"pushed_at":"2019-04-08T13:03:24.000Z","size":20,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-12T22:08:56.314Z","etag":null,"topics":["activerecord","database-transactions","ecto","ruby","ruby-gem","ruby-on-rails"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emancu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-24T14:33:08.000Z","updated_at":"2020-12-24T07:46:15.000Z","dependencies_parsed_at":"2022-11-03T06:30:44.090Z","dependency_job_id":null,"html_url":"https://github.com/emancu/ector-multi","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/emancu/ector-multi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emancu%2Fector-multi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emancu%2Fector-multi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emancu%2Fector-multi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emancu%2Fector-multi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emancu","download_url":"https://codeload.github.com/emancu/ector-multi/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emancu%2Fector-multi/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259512586,"owners_count":22869440,"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":["activerecord","database-transactions","ecto","ruby","ruby-gem","ruby-on-rails"],"created_at":"2024-10-24T09:13:10.777Z","updated_at":"2025-06-12T17:34:03.820Z","avatar_url":"https://github.com/emancu.png","language":"Ruby","readme":"# Ector::Multi\n[![Gem Version](https://badge.fury.io/rb/ector-multi.svg)](http://badge.fury.io/rb/ector-multi)\n[![Build Status](https://travis-ci.org/emancu/ector-multi.svg)](https://travis-ci.org/emancu/ector-multi)\n[![Code Climate](https://codeclimate.com/github/emancu/ector-multi/badges/gpa.svg)](https://codeclimate.com/github/emancu/ector-multi)\n[![RubyGem](https://img.shields.io/gem/dt/ector-multi.svg)](https://rubygems.org/gems/ector-multi)\n\n`Ector::Multi` is an object for grouping multiple DB operations that should be performed in a single database transaction.\n\nI literally copy the API and idea from [Ecto::Multi](https://hexdocs.pm/ecto/Ecto.Multi.html), so I'm gonna copy the documentation as well.\n\n\u003cimg src=\"https://user-images.githubusercontent.com/56375/55725543-3cf14e80-5a0e-11e9-9621-649395574ee8.png\" width=\"150\" align=\"middle\" \u003e\n\n\n## Dependencies\n\nAt this moment, `Ector::Multi` requires `ActiveRecord` as a dependency and relies on it for CRUD operations and transactions.\nEventually, I would like to be ORM-agnostic and be able to configure different ORMs and remove the hard dependency.\n\n## Getting started\n\n`Ector::Multi` is an object for grouping multiple database operations.\n\n`Ector::Multi` makes it possible to pack operations that should be performed in a single database transaction and gives a way to introspect the queued operations without actually performing them. Each operation is given a name that is unique and will identify its result in case of success or failure.\n\nAll operations will be executed in the order they were added.\n\nThe `Ector::Multi` object should be considered opaque. You can use common ruby techniques to dig into it, but accessing fields or directly modifying them is not advised.\n\n\n## Run\n\n`Ector::Multi` allows you to run arbitrary functions as part of your transaction via `run`.\nThis is especially useful when an operation depends on the value of a previous operation.\nFor this reason, the function given as a callback to run will receive all changes performed by the multi so far.\n\nThe function given to `run` must return _something_ or raise a `Ector::Multi::OperationFailure`. Raising an error will abort any further operations and make the whole multi fail.\n\n## Example\n\nLet’s look at an example definition and usage. The use case we’ll be looking into is resetting a password.\nWe need to update the account with proper information, log the request and remove all current sessions:\n\n```ruby\nmodule PasswordManager\n  def self.reset(account, params)\n    Ector::Multi.new\n    .update(:account, account, params)\n    .create(:log, Log, account_id: account.id, changed_at: Time.now)\n    .destroy_all(:clear_sessions, Session.where(account_id: account.id))\n  end\nend\n```\n\nWe can later execute it in the integration layer using `#commit`:\n\n```ruby\n  result = PasswordManager.reset(account, params).commit\n```\n\nThe resulting object, a `Ector::Multi::Result`, will tell you if it succeeded or failed. Also, it is possible to dig into the results of each operation.\n\n## Functions\n\n`multi.append(second_mutli)`\n\nAppends the second multi to the first one\n\n`multi.destroy(name, instance)`\n\nAdds a destroy operation to the multi\n\n`multi.destroy_all(name, queryable)`\n\nAdds a destroy_all operation to the multi\n\n`multi.error(name, value)`\n\nCauses the multi to fail with the given value\n\n`multi.create(name, model, attributes, \u0026block = nil)`\n\nAdds a create operation to the multi\n\n`Ector::Multi.new`\n\nReturns an empty Ector::Multi object\n\n`multi.prepend(second_multi)`\n\nPrepends the second multi to the first one\n\n`multi.run(name, \u0026run)`\n\nAdds a function to run as part of the multi\n\n`multi.to_list`\n\nReturns the list of operations stored in multi\n\n`multi.update(name, instance, updates, \u0026block = nil)`\n\nAdds an update operation to the multi\n\n`multi.update_all(name, queryable, updates, \u0026block = nil)`\n\nAdds an update_all operation to the multi\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femancu%2Fector-multi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femancu%2Fector-multi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femancu%2Fector-multi/lists"}