• Stars
    star
    107
  • Rank 323,587 (Top 7 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 11 years ago
  • Updated over 10 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Specify queries to be sent all at once to the database. Save round trips!

ActiveRecord::Futures

Gem Version Build Status Code Climate Coverage Status

Define future queries in ActiveRecord that will get executed in a single round trip to the database.

This gem allows to easily optimize an application using activerecord. All independent queries can be marked as futures, so that when you execute any of them at a later time, all the other ones will be executed as well, but the query of all of them will be executed in a single round trip to the database. That way, when you access the other results, they'll already be there, not needing to go to the database again.

The idea is heavily inspired from NHibernate's future queries

Installation

Add this line to your application's Gemfile:

gem 'activerecord-futures'

And then execute:

$ bundle

Or install it yourself as:

$ gem install activerecord-futures

Usage

If you're using postgresql or mysql2 currently, you have nothing more to do. The gem will automatically use the future enabled adapter and just work. If you are using a custom adapter, specify it in the config/database.yml file as you're used to.

Check the database support (below) section for more info.

Now let's see what this does, consider a model User, with a :name attribute:

# Build the queries and mark them as futures
users = User.where("name like 'John%'")
user_list = users.future # becomes a future relation, does not execute the query.
count = users.future_count # becomes a future calculation, does not execute the query.

# Execute any of the futures
count = count.value # trigger the future execution, both queries will get executed in one round trip!
#=> User Load (fetching Futures) (0.6ms)  SELECT `users`.* FROM `users` WHERE (name like 'John%');SELECT COUNT(*) FROM `users` WHERE (name like 'John%')

# Access the other results
user_list.to_a # does not execute the query, results from previous query get loaded

Any amount of futures can be prepared, and they will get executed as soon as one of them needs to be evaluated.

This makes this especially useful for pagination queries, since you can execute both count and page queries at once.

Rails

No configuration to do, things will Just Work.

Rack based apps (not Rails)

You will need to manually add the ActiveRecord::Futures::Middleware somewhere in the middleware stack:

use ActiveRecord::Futures::Middleware

This is to clear the futures that were defined and not triggered between requests.

Methods

#future method

ActiveRecord::Relation instances get a future method that futurizes a normal relation. The future gets executed whenever #to_a gets executed. Note that, as ActiveRecord does, enumerable methods get delegated to #to_a also, so things like #each, #map, #collect all trigger the future.

Calculation methods

You also get all the calculation methods provided by the ActiveRecord::Calculations module "futurized". More specifically you get:

  • future_count
  • future_average
  • future_minimum
  • future_maximum
  • future_sum
  • future_calculate
  • future_pluck

All future calculations are triggered with the #value method, except for the #future_pluck method, that returns an array, and is triggered with a #to_a method (or any other method that delegates to it).

Finder methods

Lastly, you also get finder methods futurized, which are:

  • future_find
  • future_first
  • future_last
  • future_exists?
  • future_all

As with the other future methods, those which return an array get triggered with the #to_a method, or the delegated ones, and those that return a value or a hash are triggered with the #value method. Note that the #find method returns an array or a value depending on the parameters provided, and so will the futurized version of the method.

Database support

SQlite

SQlite doesn't support multiple statement queries. ActiveRecord::Futures will fall back to normal query execution, that is, it will execute the future's query whenever the future is triggered, but it will not execute the other futures' queries.

MySQL

Multi statement queries are supported by the mysql2 gem since version 0.3.12b1, so you'll need to use that one or a newer one. Currently the adapter provided inherits the built-in one in Rails, and it also sets the MULTI_STATEMENTS flag to allow multiple queries in a single command. If you have an older version of the gem, ActiveRecord::Futures will fall back to normal query execution.

Postgres

The pg gem supports multiple statement queries by using the #send_query method and retrieving the results via #get_result.

Other databases

In general, ActiveRecord::Futures will look for a method #supports_futures? in the adapter. So any adapter that returns false when calling the method, or does not respond to it, will fall back to normal query execution. If you want to have support for ActiveRecord::Futures with your database, feel free to create a pull request with it, or create your own gem, or just create an issue.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

More Repositories

1

redux-immutable-state-invariant

Redux middleware that detects mutations between and outside redux dispatches. For development use only.
JavaScript
937
star
2

react-sound

Sound component to play audio in your web apps
JavaScript
485
star
3

graphql-tag.macro

Babel Macro for graphql-tag
JavaScript
167
star
4

graphql-persisted-document-loader

Webpack loader that adds a documentId to a compiled graphql document, which can be used when persisting/retrieving documents
JavaScript
81
star
5

workshop-pensando-en-react

Workshop introductorio a React
JavaScript
51
star
6

makery.js

Factory-style (via blueprints) object creation for tests. Inspired by Ruby Machinist.
JavaScript
22
star
7

fnky

A funky (and "souly"?) library for functional programming in Javascript
JavaScript
17
star
8

react-style-hot-reload

Exploring how to make react-style work with HMR and react-hot-loader
JavaScript
13
star
9

redux-state-router

Define your urls as a function of your state
JavaScript
8
star
10

cycle-poc

Playing with Cyclejs
JavaScript
5
star
11

StateMachine

State Machine pattern for .NET (inspired by ruby gem state_machine)
C#
4
star
12

rpg

This wanted be a super cool MMORPG, but I abandoned it :(
CoffeeScript
2
star
13

js-runner-fatigue

JS (runner) Fatigue - A game to cope with learning different JS stacks
JavaScript
2
star
14

graphql-client

wip
JavaScript
2
star
15

react-job-board

Quick example job board app using React.
JavaScript
2
star
16

enter-hangman

Hangman game made with React for a live coding session at Meetup.js Buenos Aires
JavaScript
2
star
17

demo_app

Some other app for ruby
Ruby
1
star
18

leoasis.github.com

My Personal Blog
JavaScript
1
star
19

stillness

Immutable manipulation helpers to aid in nested state updates
JavaScript
1
star
20

immutable-model

Immutable Model and Collection abstractions backed by Immutable.js
JavaScript
1
star
21

perf-graphql-tag

Repo to see how much time is saved when preprocessing graphql-tag calls
JavaScript
1
star
22

vows-test

Testing of the Vows module for node.js
JavaScript
1
star