{"id":22725372,"url":"https://github.com/delonnewman/activerecord-setops","last_synced_at":"2025-04-13T20:27:17.926Z","repository":{"id":56388208,"uuid":"237307158","full_name":"delonnewman/activerecord-setops","owner":"delonnewman","description":"Union, Intersect, and Difference set operations for ActiveRecord (also, SQL's UnionAll).","archived":false,"fork":false,"pushed_at":"2022-12-14T20:48:49.000Z","size":672,"stargazers_count":21,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-15T01:42:37.799Z","etag":null,"topics":["activerecord","activerecord-extension","activerecord-queries","arel","query","relational-algebra","relational-database","relational-databases","ruby","ruby-gem","ruby-on-rails","set","set-operations","set-theory","sets","sql","sql-except","sql-intersect","sql-union","sql-unionall"],"latest_commit_sha":null,"homepage":null,"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/delonnewman.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}},"created_at":"2020-01-30T21:15:06.000Z","updated_at":"2022-08-13T09:35:36.000Z","dependencies_parsed_at":"2023-01-29T01:02:18.200Z","dependency_job_id":null,"html_url":"https://github.com/delonnewman/activerecord-setops","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delonnewman%2Factiverecord-setops","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delonnewman%2Factiverecord-setops/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delonnewman%2Factiverecord-setops/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delonnewman%2Factiverecord-setops/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/delonnewman","download_url":"https://codeload.github.com/delonnewman/activerecord-setops/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229089204,"owners_count":18018390,"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","activerecord-extension","activerecord-queries","arel","query","relational-algebra","relational-database","relational-databases","ruby","ruby-gem","ruby-on-rails","set","set-operations","set-theory","sets","sql","sql-except","sql-intersect","sql-union","sql-unionall"],"created_at":"2024-12-10T16:09:29.376Z","updated_at":"2024-12-10T16:09:30.072Z","avatar_url":"https://github.com/delonnewman.png","language":"Ruby","readme":"![Ruby](https://github.com/delonnewman/activerecord-setops/workflows/Ruby/badge.svg)\n[![Gem Version](https://badge.fury.io/rb/activerecord-setops.svg)](https://badge.fury.io/rb/activerecord-setops)\n[![Contact me on Codementor](https://www.codementor.io/m-badges/delonnewman/book-session.svg)](https://www.codementor.io/@delonnewman?refer=badge)\n\n\u003ca href=\"https://www.buymeacoffee.com/delonnewman\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png\" alt=\"Buy Me A Coffee\" style=\"height: 60px !important;width: 217px !important;\" \u003e\u003c/a\u003e\n\n# ActiveRecord::Setops\n\nUnion, Intersect, and Difference set operations for ActiveRecord (also, SQL's UnionAll).\nHas only been tested with Rails 5.\n\n# Synopsis\n\n```ruby\nclass Student \u003c ActiveRecord::Base; end\nclass Employee \u003c ActiveRecord::Base; end\n\n(Student.select(:name, :birth_date) | Employee.select(:name, :birth_date)).where(\"name like John%\")\n```\n\n# Why?\n\nJoins can be difficult to reason about in Arel (and SQL for that matter). Many joins can be replaced\nwith set operations which are much simpler beasts, may offer performance gains, and have consistent\nmathematical properties. But these operations while present in Arel are missing in ActiveRecord. This\nmodule attempts to correct this lack.\n\n# Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'activerecord-setops'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install activerecord-setops\n\n# Non-Installation\n\nIf you'd like the functionality, but would prefer to avoid yet another dependency, please fill free to paste the following code into your nearest lib directory, I'm certain it's not perfect but it has been [tested](spec/active_record/setops_spec.rb) with Rails 5, and is being used in production.\n\n```ruby\nmodule ActiveRecord\n  class Relation\n    def union(other)\n      binary_operation(Arel::Nodes::Union, other)\n    end\n    alias | union\n\n    def union_all(other)\n      binary_operation(Arel::Nodes::UnionAll, other)\n    end\n    alias + union_all\n\n    def intersect(other)\n      binary_operation(Arel::Nodes::Intersect, other)\n    end\n    alias \u0026 intersect\n\n    def difference(other)\n      binary_operation(Arel::Nodes::Except, other)\n    end\n    alias - difference\n\n    private\n\n    def binary_operation(op_class, other)\n      @klass.unscoped.from(Arel::Nodes::TableAlias.new(op_class.new(self.arel.ast, other.arel.ast), @klass.arel_table.name))\n    end\n  end\nend\n```\n\n# See Also\n\n- [Sequel](http://sequel.jeremyevans.net)\n- [SQL Set Operations](https://en.wikipedia.org/wiki/Set_operations_(SQL))\n- [active_record_union](https://github.com/brianhempel/active_record_union)\n","funding_links":["https://www.buymeacoffee.com/delonnewman"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdelonnewman%2Factiverecord-setops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdelonnewman%2Factiverecord-setops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdelonnewman%2Factiverecord-setops/lists"}