6 Frameworks for Generating New Business Ideas

Resources and tips to help aspiring entrepreneurs explore and discover new business opportunities.

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




Reading Arel of ActiveRecord

From Ruby to SQL

Arel is an AST manager used in ActiveRecord to create SQL query. Every SQL statements are represented as ruby code in Arel. Because of this, it enable to write a complicated SQL query without using raw SQL string. But it’s not recommended to use Arel in the application because it’s a private API.

I’ll dive into the internal of Arel in this article. I’ll explain how it works when generating SQL with simple code example.

I’m not an expert of this subject. Please correct me if i’m wrong.

Arel is located in ActiveRecord gem. And has these kind of directory structure.

As I said, Arel is an AST manager. So there are classes that represents each statements. They are located in nodes directory.

This contains classes for each table attributes with type such as STRING, TIME or BOOLEAN, etc…

This contains AST nodes visitor and SQL engine specific codes. (for MySQL, PostgreSQL, etc…)

Table class has methods to access Arel::SelectManager, Arel::Attribute and Nodes::TableAlias. And also has methods to construct query.(e.g. where, join, group, order, having, etc...)

Attribute class represents attributes that belongs to the table.

Example

This seems to be a node forSELECT statement. But it's different there is another node called Arel::Nodes::SelectStatement which represents only SELECT. Arel::SelectManager has convenient methods to create AST tree.

There are another class like this.

A base class of each AST node classes.

Contain AST node visitors methods which used on creating SQL string. I’ll explain in later.

This allows to create a AST node for statement which not being declared in Arel by default. Here is a usage in Arel::FactoryMethods.

I’ll follow what happens inside Arel when running this example code.

First, where in select manager is defined in Arel::TreeManager.

Simple enough. If the argument is Arel::TreeManager then fetch AST from it. And put into @ctx.wheres. Otherwise, put expr directly into @ctx.wheres. As Arel::TreeManager is included in Arel::SelectManager, this @ctx is same as it on Arel::TreeManager.

‌Table.engine is initialized on ActiveRecord loaded. So this is a reference to ActiveRecord to the module.

engine.connection is defined in ActiveRecord::ConnectionHandling. This is same method referenced with ActiveRecord::Base.connection. This method returns a connection from connection pool.

Arel::Visitors::MySQL is a subclass of Arel::Visitors::ToSql. Major logics are written in Arel::Visitors::ToSql. Arel::Visitors::MySQL only has some engine specific code.

What happens inside when you call visit?

Here is examples.

How about with the example code?

The @ast has following structure.

Also @wheres of the first @cores looks like this.

We know that o is an AST node of Arel::Nodes::SelectStatement in this case. And collector is Arel::Collectors::SQLString.

Nothing happens on if o.with block because it's empty.

I think I’ve got a feeling of how Arel working. So I’m gonna finish this article.

Thanks for reading!!

Build crazy queries with ActiveRecord and Arel

Add a comment

Related posts:

Recipes for Extending SaaS Platforms

How does an enterprise get the most from their digital platform provider? Understanding how to customise and build a unified platform from different SaaS platforms is key.