ActiveRecord::Refined

Adding clean and powerful query syntax on Active Record using refinements.

Author.
  joins(:posts) { :posts[:author_id] == :authors[:id] }.
  where { :authors[:age].in?(20..40) & (:posts[:published] == true) }
# SELECT "authors".* FROM "authors"
#   INNER JOIN "posts" ON "posts"."author_id" = "authors"."id"
#   WHERE "authors"."age" BETWEEN 20 AND 40 AND "posts"."published" = TRUE

Inside a block, symbols denote columns of the receiver's table, and :table[:column] denotes a qualified column. That holds in every position — on the right of a comparison too, so :age == :retirement_age compares two columns. A value is written as its literal, an enum's as its string; a symbol naming no column of the model is refused rather than compared against nothing anyone meant.

Try it in your browser — Ruby 4.1, Active Record, SQLite and PostgreSQL run in the page, so the examples build real SQL and return real rows without a ruby-master build of your own.

Reference

  • BlockSyntax — what a symbol answers to inside a block: as, asc, desc, collate, [], and through it the conditions of Predications and the operators of Arithmetics.
  • BlockContext — what a block can call: the aggregates, the scalar and window functions, CASE, sql, fn.
  • QueryMethods — what the relation takes: the block forms of where and the rest, the joins, from_cte, distinct_on, lateral.
  • Writesupdate_all and upsert_all with a block.
  • Dialect — one class per family of SQL spellings, and register for an adapter of your own.

Guides

One topic at a time, each with the SQL it builds and where the adapters differ:

  • Conditions — comparisons, LIKE, IN, NULL, true?, regular expressions, subqueries, ANY and ALL, arrays.
  • Joins — the ON as a block, table aliases, subqueries and LATERAL.
  • Aggregates and functionscount, filter, string_agg, the scalar functions, the clock, durations, extract and cast.
  • Expressions — arithmetic, the bitwise operators, CASE.
  • JSONdig, bury, except, key?, keys, the JSON aggregates, and where the adapters' JSON types part.
  • Window functionsover, partition, order, frames.
  • Aliases, ordering and collation
  • GroupingDISTINCT ON, GROUPING SETS, ROLLUP, CUBE.
  • Common table expressionswith_recursive and from_cte.
  • Writingupdate_all and upsert_all.
  • Time zones — what a block converts and what it leaves to the session.

The repository's README, on GitHub, has the history, the requirements, and how the tests and the release are run.