5

Rails 7 Arel adds support for FILTER clause

 2 years ago
source link: https://blog.saeloun.com/2022/05/31/rails-7-arel-filter-support
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Introduction

What is Arel?

Arel is a SQL generator library for Ruby. It allows us to write complex SQL queries in a semantic, reusable fashion by using an SQL AST (Abstract Syntax Tree-like) approach.

It represents the SQL syntax as nodes similar to how we use an expression tree to represent mathematical expressions.

arel-tree.png

Arel uses different predications (analogous to operators for the expression tree) such as count, eq, not_eq, gt, etc. to construct the SQL

t = User.arel_table
User.where(t[:first_name].eq('Rohit')).to_sql
#=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"first_name\" = 'Rohit'"
t.

What is the SQL FILTER clause?

The filter clause in SQL extends aggregate functions (sum, avg, count etc.) by an additional where clause.

Syntax:

COUNT(<expression>) FILTER(WHERE <condition>)

Rails 7 added support for the FILTER binary prediction to support and generate this filter clause in Arel

Before

t = User.arel_table
Arel.star.count.filter(t[:first_name].eq("Rohit")).to_sql
#=> NoMethodError: undefined method `filter' for #<Arel::Nodes::Count:0x00007f7f71fd1dd8>

After

t = User.arel_table
Arel.star.count.filter(t[:first_name].eq("Rohit")).to_sql
#=> "COUNT(*) FILTER (WHERE \"users\".\"first_name\" = 'Rohit')"

t = Order.arel_table
t[:amount].sum.filter(t(:item_count).lt(2)).to_sql
#=> "SUM(\"orders\".\"amount\") FILTER (WHERE \"orders\".\"item_count\" < 2)"

# With alias
t[:amount].sum.filter(t[:item_count].lteq(3).as('small_orders_total_amount')).to_sql
#=> "SUM(\"orders\".\"amount\") FILTER (WHERE \"orders\".\"item_count\" <= 3 AS small_orders_total_amount)"

Note: The filter clause is currently supported only for PostgreSQL(9.4+) and SQLite(3.30+) databases


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK