{"id":13878572,"url":"https://github.com/djezzzl/n1_loader","last_synced_at":"2025-04-13T00:47:34.731Z","repository":{"id":38452597,"uuid":"439619944","full_name":"djezzzl/n1_loader","owner":"djezzzl","description":"Loader to solve N+1 issues for good. Highly recommended for GraphQL API.","archived":false,"fork":false,"pushed_at":"2023-12-18T06:51:33.000Z","size":129,"stargazers_count":227,"open_issues_count":0,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-13T00:47:28.437Z","etag":null,"topics":["activerecord","graphql","nplus1","rails","ruby"],"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/djezzzl.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-12-18T13:18:31.000Z","updated_at":"2025-03-05T09:24:23.000Z","dependencies_parsed_at":"2023-12-15T10:03:24.909Z","dependency_job_id":"e6b0828f-2b1e-4239-8af1-a97c32c5a31e","html_url":"https://github.com/djezzzl/n1_loader","commit_stats":{"total_commits":109,"total_committers":6,"mean_commits":"18.166666666666668","dds":0.1009174311926605,"last_synced_commit":"88a924616020aa9ff92c9c39874afe305f212ad2"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djezzzl%2Fn1_loader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djezzzl%2Fn1_loader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djezzzl%2Fn1_loader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djezzzl%2Fn1_loader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/djezzzl","download_url":"https://codeload.github.com/djezzzl/n1_loader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650434,"owners_count":21139672,"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","graphql","nplus1","rails","ruby"],"created_at":"2024-08-06T08:01:53.526Z","updated_at":"2025-04-13T00:47:34.696Z","avatar_url":"https://github.com/djezzzl.png","language":"Ruby","funding_links":["https://opencollective.com/n1_loader","https://opencollective.com/n1_loader/backer/0/website","https://opencollective.com/n1_loader/backer/1/website","https://opencollective.com/n1_loader/backer/2/website","https://opencollective.com/n1_loader/backer/3/website","https://opencollective.com/n1_loader/backer/4/website","https://opencollective.com/n1_loader/backer/5/website","https://opencollective.com/n1_loader/backer/6/website","https://opencollective.com/n1_loader/backer/7/website","https://opencollective.com/n1_loader/backer/8/website","https://opencollective.com/n1_loader/backer/9/website","https://opencollective.com/n1_loader/backer/10/website","https://opencollective.com/n1_loader/backer/11/website","https://opencollective.com/n1_loader/backer/12/website","https://opencollective.com/n1_loader/backer/13/website","https://opencollective.com/n1_loader/backer/14/website","https://opencollective.com/n1_loader/backer/15/website","https://opencollective.com/n1_loader/backer/16/website","https://opencollective.com/n1_loader/backer/17/website","https://opencollective.com/n1_loader/backer/18/website","https://opencollective.com/n1_loader/backer/19/website","https://opencollective.com/n1_loader/backer/20/website","https://opencollective.com/n1_loader/backer/21/website","https://opencollective.com/n1_loader/backer/22/website","https://opencollective.com/n1_loader/backer/23/website","https://opencollective.com/n1_loader/backer/24/website","https://opencollective.com/n1_loader/backer/25/website","https://opencollective.com/n1_loader/backer/26/website","https://opencollective.com/n1_loader/backer/27/website","https://opencollective.com/n1_loader/backer/28/website","https://opencollective.com/n1_loader/backer/29/website"],"categories":["Ruby"],"sub_categories":[],"readme":"# N1Loader\n\n[![Gem Version][3]][4]\n[![][11]][12]\n[![][13]][14]\n[![][9]][10]\n\nN1Loader is designed to provide a simple way for avoiding [N+1 issues][7] of any kind. \nFor example, it can help with resolving N+1 for:\n- database querying (most common case)\n- 3rd party service calls\n- complex calculations\n- and many more\n\n\u003e If the project helps you or your organization, I would be very grateful if you [contribute][15] or [donate][10].  \n\u003e Your support is an incredible motivation and the biggest reward for my hard work.\n\n___Support:___ ActiveRecord 5, 6, and 7.\n\nFollow me and stay tuned for the updates:\n- [LinkedIn](https://www.linkedin.com/in/evgeniydemin/)\n- [Medium](https://evgeniydemin.medium.com/)\n- [Twitter](https://twitter.com/EvgeniyDemin/)\n- [GitHub](https://github.com/djezzzl)\n\n## Killer feature for GraphQL API\n\nN1Loader in combination with [ArLazyPreload][6] is a killer feature for your GraphQL API. \nGive it a try now and see incredible results instantly! Check out the [example](examples/graphql.rb) and start benefiting from it in your projects!\n\n```ruby\ngem 'n1_loader', require: 'n1_loader/ar_lazy_preload'\n```\n\n## Enhance [ActiveRecord][5]\n\nAre you working with well-known Rails application? Try it out and see how well N1Loader fulfills missing gaps when you can't define ActiveRecord associations!\nCheck out the detailed [guide](guides/enhanced-activerecord.md) with examples or its [short version](examples/active_record_integration.rb).\n\n```ruby\ngem 'n1_loader', require: 'n1_loader/active_record'\n```\n\nAre you ready to forget about N+1 once and for all? Install [ArLazyPreload][6] and see dreams come true!\n\n```ruby\ngem 'n1_loader', require: 'n1_loader/ar_lazy_preload'\n```\n\n## Standalone mode\n\nAre you not working with [ActiveRecord][5]? N1Loader is ready to be used as standalone solution! ([full snippet](examples/core.rb))\n\n```ruby\ngem 'n1_loader'\n```\n\n## How to use it?\n\nN1Loader provides DSL that allows you to define N+1 ready loaders that can \nbe injected into your objects in a way that you can avoid N+1 issues.\n\n\u003e _Disclaimer_: examples below are working but designed to show N1Loader potentials only.\nIn real live applications, N1Loader can be applied anywhere and in more [elegant way](examples/isolated_loader.rb).  \n\nLet's look at simple example below ([full snippet](examples/active_record_integration.rb)):\n```ruby\nclass User \u003c ActiveRecord::Base\n  has_many :payments\n\n  n1_optimized :payments_total do |users|\n    total_per_user = \n      Payment.group(:user_id)\n        .where(user: users)\n        .sum(:amount)\n        .tap { |h| h.default = 0 }\n\n    users.each do |user|\n      total = total_per_user[user.id]\n      fulfill(user, total)\n    end\n  end\nend\n\nclass Payment \u003c ActiveRecord::Base\n  belongs_to :user\n\n  validates :amount, presence: true\nend\n\n# A user has many payments. \n# Assuming, we want to know for group of users, what is a total of their payments, we can do the following:\n\n# Has N+1 issue\np User.all.map { |user| user.payments.sum(\u0026:amount) }\n\n# Has no N+1 but we load too many data that we don't actually need\np User.all.includes(:payments).map { |user| user.payments.sum(\u0026:amount) }\n\n# Has no N+1 and we load only what we need\np User.all.includes(:payments_total).map { |user| user.payments_total }\n```\n\nLet's assume now, that we want to calculate the total of payments for the given period for a group of users. \nN1Loader can do that as well! ([full snippet](examples/arguments_support.rb)) \n\n```ruby\nclass User \u003c ActiveRecord::Base\n  has_many :payments\n\n  n1_optimized :payments_total do\n    argument :from\n    argument :to\n\n    def perform(users)\n      total_per_user =\n        Payment\n          .group(:user_id)\n          .where(created_at: from..to)\n          .where(user: users)\n          .sum(:amount)\n          .tap { |h| h.default = 0 }\n\n      users.each do |user|\n        total = total_per_user[user.id]\n        fulfill(user, total)\n      end\n    end\n  end\nend\n\nclass Payment \u003c ActiveRecord::Base\n  belongs_to :user\n\n  validates :amount, presence: true\nend\n\n# Has N+1\np User.all.map { |user| user.payments.select { |payment| payment.created_at \u003e= from \u0026\u0026 payment.created_at \u003c= to }.sum(\u0026:amount) }\n\n# Has no N+1 but we load too many data that we don't need\np User.all.includes(:payments).map { |user| user.payments.select { |payment| payment.created_at \u003e= from \u0026\u0026 payment.created_at \u003c= to }.sum(\u0026:amount) }\n\n# Has no N+1 and calculation is the most efficient\np User.all.includes(:payments_total).map { |user| user.payments_total(from: from, to: to) }\n```\n\n## Features and benefits\n\n- N1Loader doesn't use Promises which means it's easy to debug\n- Doesn't require injection to objects, can be used in [isolation](examples/isolated_loader.rb)\n- Loads data [lazily](examples/lazy_loading.rb)\n- Loaders can be [shared](examples/shared_loader.rb) between multiple classes\n- Loaded data can be [re-fetched](examples/reloading.rb)\n- Loader can be optimized for [single cases](examples/single_case.rb)\n- Loader support [arguments](examples/arguments_support.rb)\n- Has [integration](examples/active_record_integration.rb) with [ActiveRecord][5] which makes it brilliant\n- Has [integration](examples/ar_lazy_integration.rb) with [ArLazyPreload][6] which makes it excellent\n\n### Feature killer for [ArLazyPreload][6] integration with isolated loaders\n\nIn [version 1.6.0](CHANGELOG.md#160---20221019) isolated loaders were integrated with [ArLazyPreload][6] context.\nThis means, it isn't required to inject `N1Loader` into your [ActiveRecord][5] models to avoid N+1 issues out of the box.\nIt is especially great as many engineers are trying to avoid extra coupling between their models/services when it's possible.\nAnd this feature was designed exactly for this without losing an out of a box solution for N+1.\n\nWithout further ado, please have a look at the [example](examples/ar_lazy_integration_with_isolated_loader.rb).\n\n_Spoiler:_ as soon as you have your loader defined, it will be as simple as `Loader.for(element)` to get your data efficiently and without N+1.\n\n## Funding\n\n### Open Collective Backers\n\nYou're an individual who wants to support the project with a monthly donation. Your logo will be available on the Github page. [[Become a backer](https://opencollective.com/n1_loader#backer)]\n\n\u003ca href=\"https://opencollective.com/n1_loader/backer/0/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/0/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/1/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/1/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/2/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/2/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/3/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/3/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/4/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/4/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/5/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/5/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/6/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/6/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/7/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/7/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/8/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/8/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/9/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/9/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/10/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/10/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/11/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/11/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/12/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/12/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/13/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/13/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/14/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/14/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/15/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/15/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/16/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/16/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/17/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/17/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/18/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/18/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/19/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/19/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/20/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/20/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/21/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/21/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/22/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/22/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/23/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/23/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/24/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/24/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/25/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/25/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/26/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/26/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/27/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/27/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/28/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/28/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/backer/29/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/backer/29/avatar.svg\"\u003e\u003c/a\u003e\n\n### Open Collective Sponsors\n\nYou're an organization that wants to support the project with a monthly donation. Your logo will be available on the Github page. [[Become a sponsor](https://opencollective.com/n1_loader#sponsor)]\n\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/0/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/0/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/1/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/1/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/2/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/2/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/3/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/3/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/4/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/4/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/5/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/5/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/6/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/6/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/7/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/7/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/8/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/8/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/9/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/9/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/10/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/10/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/11/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/11/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/12/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/12/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/13/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/13/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/14/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/14/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/15/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/15/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/16/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/16/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/17/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/17/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/18/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/18/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/19/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/19/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/20/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/20/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/21/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/21/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/22/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/22/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/23/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/23/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/24/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/24/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/25/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/25/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/26/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/26/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/27/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/27/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/28/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/28/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/n1_loader/sponsor/29/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/n1_loader/sponsor/29/avatar.svg\"\u003e\u003c/a\u003e\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/djezzzl/n1_loader. \nThis project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](CODE_OF_CONDUCT.md).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the N1Loader project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).\n\n## Changelog\n\n*N1Loader*'s changelog is available [here](CHANGELOG.md).\n\n## Copyright\n\nCopyright (c) Evgeniy Demin. See [LICENSE.txt](LICENSE.txt) for further details.\n\n[3]: https://badge.fury.io/rb/n1_loader.svg\n[4]: https://badge.fury.io/rb/n1_loader\n[5]: https://github.com/rails/rails/tree/main/activerecord\n[6]: https://github.com/DmitryTsepelev/ar_lazy_preload\n[7]: https://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem-in-orm-object-relational-mapping\n[8]: https://github.com/djezzzl/n1_loader\n[9]: https://opencollective.com/n1_loader/tiers/badge.svg\n[10]: https://opencollective.com/n1_loader#support\n[11]: https://github.com/djezzzl/n1_loader/actions/workflows/tests.yml/badge.svg?branch=master\n[12]: https://github.com/djezzzl/n1_loader/actions/workflows/tests.yml?query=event%3Aschedule\n[13]: https://github.com/djezzzl/n1_loader/actions/workflows/rubocop.yml/badge.svg?branch=master\n[14]: https://github.com/djezzzl/n1_loader/actions/workflows/rubocop.yml?query=event%3Aschedule\n[15]: https://github.com/djezzzl/n1_loader#contributing\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjezzzl%2Fn1_loader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjezzzl%2Fn1_loader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjezzzl%2Fn1_loader/lists"}