10

Rails 7.1 Allows ActiveRecord reselect Query Method To Accept Hash

 8 months ago
source link: https://blog.saeloun.com/2023/12/15/rails-7-1-allows-activerecord-reselect-to-accept-hash-values/
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

Rails 7.1 Allows ActiveRecord reselect Query Method To Accept Hash

Dec 15, 2023

authorImg

Prasanth Chaduvula

I'm a React, Javascript & Rails full-stack Software Engineer. I have been working remotely for the past two years in a remote village. Before joining as a Software Engineer I founded kwiq - a hyperlocal delivery startup to deliver things in remote villages.

2 minute read

ActiveRecord::QueryMethods are methods provided by Rails to build and execute database queries.

The select method allows us to select specific fields from the database.

The reselect method in ActiveRecord allows us to change the previously set select statement.

Under the hood, reselect is short-hand for unscope(:select).select(fields). Basically we’re unscoping the entire select statement.

User.select(:email).reselect(:first_name)
SELECT "users"."first_name" FROM "users"

Before

Before 7.1, we were able to reselect specific fields with column names as an array of strings or symbols, or we can provide raw SQL.

Client.select(:name, :phone).reselect(:name, :email)

# => output
SELECT "clients"."name", "clients"."email" FROM "clients"
Client.select("name", "phone").reselect("name", "email")

# => output
SELECT "clients"."name", "clients"."email" FROM "clients"
Client.select("name, phone").reselect("name, email")

# => output
SELECT name, email FROM "clients"

But to select the columns from an associated model, we only have the option to provide raw SQL.

Client
  .joins(:projects)
  .select(:name, :phone, "projects.billable")
  .reselect(:name, :email, "projects.billable")

# => output
SELECT "clients"."name", "clients"."email", "projects"."billable" 
FROM "clients" 
INNER JOIN "projects" ON "projects"."client_id" = "clients"."id"
Client
  .joins(:projects)
  .select("clients.name, clients.phone, projects.billable")
  .reselect("clients.name, clients.email, projects.billable")

# => output
SELECT clients.name, clients.email, projects.billable 
FROM "clients" 
INNER JOIN "projects" ON "projects"."client_id" = "clients"."id"
Client
  .joins(:projects)
  .select("clients.name AS client_name, clients.phone AS client_phone, projects.billable AS project_billable")
  .reselect("clients.name AS client_name, clients.email AS client_email, projects.billable AS project_billable")

# => output
SELECT clients.name AS client_name, clients.email AS client_email, projects.billable AS project_billable 
FROM "clients" 
INNER JOIN "projects" ON "projects"."client_id" = "clients"."id"

After

Rails 7.1 allows ActiveRecord::QueryMethods#reselect to accept hash of columns and aliases and no need to use the raw version of the query anymore.

Let’s take a look at the same code after the change.

Client
  .joins(:projects)
  .select(:name, :phone, "projects.billable")
  .reselect(:name, :email, projects: [:billable])

# => output
SELECT "clients"."name", "clients"."email", "projects"."billable" 
FROM "clients" 
INNER JOIN "projects" ON "projects"."client_id" = "clients"."id"
Client
  .joins(:projects)
  .select("clients.name, clients.phone, projects.billable")
  .reselect(clients: [:name, :email], projects: [:billable])

# => output
SELECT "clients"."name", "clients"."email", "projects"."billable" 
FROM "clients" 
INNER JOIN "projects" ON "projects"."client_id" = "clients"."id"
Client
  .joins(:projects)
  .select("clients.name AS client_name, clients.phone AS client_phone, projects.billable AS project_billable")
  .reselect(
    clients:  {name: :client_name, email: :client_email},
    projects: { billable: :project_billable}
  )

# => output
SELECT "clients"."name" AS client_name, "clients"."email" AS client_email, "projects"."billable" AS project_billable 
FROM "clients" 
INNER JOIN "projects" ON "projects"."client_id" = "clients"."id"

In the same way, Rails 7.1 allows ActiveRecord::QueryMethods#select to accept hash

Share this post!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK