Skip to content

propose Arel usage. #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,59 @@ List here all the section and stuff you would like or wish someone could to talk
* develop/adopt an instrument to automatically generate/update comments in the code
* GDPR

# Rails Arel

Instead of using raw SQL for complex queries we can use [Rails/Arel](https://github.com/rails/arel).
Using Arel makes your code more railsish and sexy
(grants +3 RoR power and colleagues respect (not guaranteed)).

### Usage example
We've got companies with users. Let's list companies where users haven't logged in last week and count them.

```postgresql
SELECT "companies"."name", COUNT("users"."id") FROM "users"
INNER JOIN "companies" ON "companies"."id" = "users"."company_id"
WHERE ("users"."last_sign_in_at" < (current_timestamp - '7 days'::interval)
OR "users"."last_sign_in_at" IS NULL)
GROUP BY "companies"."id"
```

Without Arel:

```ruby
User.joins(:company)
.where('users.last_sign_in_at < ? or users.last_sign_in_at is null', 7.days.ago)
.group('companies.id')
.pluck('companies.name', 'count(users.id)')
```

With Arel:

```ruby
company = Company.arel_table
user = User.arel_table
last_sign_in_at = user[:last_sign_in_at]
User.joins(:company)
.where(last_sign_in_at.lt(7.days.ago).or(last_sign_in_at.eq(nil)))
.group(company[:id])
.pluck(company[:name], user[:id].count)
```

Though Arel syntax might seem more verbose, it hides much power within.
You'll see it when you need to add variable column set with different order/conditions.
It allows you to easily avoid possible injections and typos.

### Arel helps when:
* making comparison `> (gt)`, `< (lt)`, `>= (gteq)`, `<= (lteq)`
* adding conditions to left join
* re-using complex tables/fields with aliases
* building configurable DB requests
* safely apply order and direction
* ...

# Changes
* ...
* varaby_m - Arel section
* ciappa_m - Expand the comments section
* philib_j - Add information about r.sh
* varaby_m - Add section about dependencies' licenses
Expand Down