All Projects → djezzzl → n1_loader

djezzzl / n1_loader

Licence: MIT license
Loader to solve N+1 issues for good. Highly recommended for GraphQL API.

Programming Languages

ruby
36898 projects - #4 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to n1 loader

Coloquent
Javascript/Typescript library mapping objects and their interrelations to JSON API, with a clean, fluent ActiveRecord-like (e.g. similar to Laravel's Eloquent) syntax for creating, retrieving, updating and deleting model objects.
Stars: ✭ 149 (-18.13%)
Mutual labels:  activerecord
Activerecord Turntable
ActiveRecord Sharding Plugin
Stars: ✭ 206 (+13.19%)
Mutual labels:  activerecord
Octopus
Database Sharding for ActiveRecord
Stars: ✭ 2,496 (+1271.43%)
Mutual labels:  activerecord
Activejpa
A simple active record pattern library in java that makes programming DAL easier
Stars: ✭ 172 (-5.49%)
Mutual labels:  activerecord
Ar Softdelete
Soft delete behavior for ActiveRecord
Stars: ✭ 188 (+3.3%)
Mutual labels:  activerecord
Anima
Minimal database operation library.
Stars: ✭ 210 (+15.38%)
Mutual labels:  activerecord
Graphql Query Resolver
Minimize N+1 queries generated by GraphQL and ActiveRecord
Stars: ✭ 148 (-18.68%)
Mutual labels:  activerecord
Scenic
Scenic is maintained by Derek Prior, Caleb Hearth, and you, our contributors.
Stars: ✭ 2,856 (+1469.23%)
Mutual labels:  activerecord
Jsonapi Utils
Build JSON API-compliant APIs on Rails with no (or less) learning curve.
Stars: ✭ 191 (+4.95%)
Mutual labels:  activerecord
Seamless database pool
Add support for master/slave database clusters in ActiveRecord to improve performance.
Stars: ✭ 222 (+21.98%)
Mutual labels:  activerecord
Ldaprecord Laravel
Multi-domain LDAP Authentication & Management for Laravel.
Stars: ✭ 178 (-2.2%)
Mutual labels:  activerecord
Groupify
Add group and membership functionality to your Rails models
Stars: ✭ 187 (+2.75%)
Mutual labels:  activerecord
Secondbase
Seamless second database integration for Rails.
Stars: ✭ 216 (+18.68%)
Mutual labels:  activerecord
Ldaprecord
A fully-featured LDAP framework.
Stars: ✭ 159 (-12.64%)
Mutual labels:  activerecord
Activerecord Postgres enum
Integrate PostgreSQL's enum data type into ActiveRecord's schema and migrations.
Stars: ✭ 227 (+24.73%)
Mutual labels:  activerecord
Querybuilder
SQL query builder, written in c#, helps you build complex queries easily, supports SqlServer, MySql, PostgreSql, Oracle, Sqlite and Firebird
Stars: ✭ 2,111 (+1059.89%)
Mutual labels:  activerecord
Randumb
Adds ability to pull back random records from Active Record
Stars: ✭ 208 (+14.29%)
Mutual labels:  activerecord
doc
QuickPerf documentation: https://github.com/quick-perf/doc/wiki/QuickPerf
Stars: ✭ 22 (-87.91%)
Mutual labels:  nplus1
Occams Record
The missing high-efficiency query API for ActiveRecord
Stars: ✭ 240 (+31.87%)
Mutual labels:  activerecord
Activerecord json validator
🔩 ActiveRecord::JSONValidator makes it easy to validate JSON attributes against a JSON schema.
Stars: ✭ 220 (+20.88%)
Mutual labels:  activerecord

N1Loader

Gem Version

N1Loader is designed to provide a simple way for avoiding N+1 issues of any kind. For example, it can help with resolving N+1 for:

  • database querying (most common case)
  • 3rd party service calls
  • complex calculations
  • and many more

If the project helps you or your organization, I would be very grateful if you contribute or donate.
Your support is an incredible motivation and the biggest reward for my hard work.

Support: ActiveRecord 5, 6, and 7.

Follow me and stay tuned for the updates:

Killer feature for GraphQL API

N1Loader in combination with ArLazyPreload is a killer feature for your GraphQL API. Give it a try now and see incredible results instantly! Check out the example and start benefiting from it in your projects!

gem 'n1_loader', require: 'n1_loader/ar_lazy_preload'

Enhance ActiveRecord

Are 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! Check out the detailed guide with examples or its short version.

gem 'n1_loader', require: 'n1_loader/active_record'

Are you ready to forget about N+1 once and for all? Install ArLazyPreload and see dreams come true!

gem 'n1_loader', require: 'n1_loader/ar_lazy_preload'

Standalone mode

Are you not working with ActiveRecord? N1Loader is ready to be used as standalone solution! (full snippet)

gem 'n1_loader'

How to use it?

N1Loader provides DSL that allows you to define N+1 ready loaders that can be injected into your objects in a way that you can avoid N+1 issues.

Disclaimer: examples below are working but designed to show N1Loader potentials only. In real live applications, N1Loader can be applied anywhere and in more elegant way.

Let's look at simple example below (full snippet):

class User < ActiveRecord::Base
  has_many :payments

  n1_optimized :payments_total do |users|
    total_per_user = 
      Payment.group(:user_id)
        .where(user: users)
        .sum(:amount)
        .tap { |h| h.default = 0 }

    users.each do |user|
      total = total_per_user[user.id]
      fulfill(user, total)
    end
  end
end

class Payment < ActiveRecord::Base
  belongs_to :user

  validates :amount, presence: true
end

# A user has many payments. 
# Assuming, we want to know for group of users, what is a total of their payments, we can do the following:

# Has N+1 issue
p User.all.map { |user| user.payments.sum(&:amount) }

# Has no N+1 but we load too many data that we don't actually need
p User.all.includes(:payments).map { |user| user.payments.sum(&:amount) }

# Has no N+1 and we load only what we need
p User.all.includes(:payments_total).map { |user| user.payments_total }

Let's assume now, that we want to calculate the total of payments for the given period for a group of users. N1Loader can do that as well! (full snippet)

class User < ActiveRecord::Base
  has_many :payments

  n1_optimized :payments_total do
    argument :from
    argument :to

    def perform(users)
      total_per_user =
        Payment
          .group(:user_id)
          .where(created_at: from..to)
          .where(user: users)
          .sum(:amount)
          .tap { |h| h.default = 0 }

      users.each do |user|
        total = total_per_user[user.id]
        fulfill(user, total)
      end
    end
  end
end

class Payment < ActiveRecord::Base
  belongs_to :user

  validates :amount, presence: true
end

# Has N+1
p User.all.map { |user| user.payments.select { |payment| payment.created_at >= from && payment.created_at <= to }.sum(&:amount) }

# Has no N+1 but we load too many data that we don't need
p User.all.includes(:payments).map { |user| user.payments.select { |payment| payment.created_at >= from && payment.created_at <= to }.sum(&:amount) }

# Has no N+1 and calculation is the most efficient
p User.all.includes(:payments_total).map { |user| user.payments_total(from: from, to: to) }

Features and benefits

Feature killer for ArLazyPreload integration with isolated loaders

In version 1.6.0 isolated loaders were integrated with ArLazyPreload context. This means, it isn't required to inject N1Loader into your ActiveRecord models to avoid N+1 issues out of the box. It is especially great as many engineers are trying to avoid extra coupling between their models/services when it's possible. And this feature was designed exactly for this without losing an out of a box solution for N+1.

Without further ado, please have a look at the example.

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.

Funding

Open Collective Backers

You'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]

Open Collective Sponsors

You'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]

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/djezzzl/n1_loader. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the N1Loader project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

Changelog

N1Loader's changelog is available here.

Copyright

Copyright (c) Evgeniy Demin. See LICENSE.txt for further details.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].