- vừa được xem lúc

How ActiveRecord builds query?

0 0 15

Người đăng: LamDN

Theo Viblo Asia

Nếu là một Rails developer, chắc hẳn bạn cũng đã từng làm việc với ActiveRecord và thấy được sức mạnh của nó. Nhưng đã bao giờ bạn tự hỏi, làm thế nào nó có thể tạo ra được những câu query phức tạp như vậy. Ngày hôm nay chúng ta sẽ đi tìm câu trả lời cho câu hỏi này.

Abstract Syntax Tree

Điều đầu tiên bạn cần biết là ActiveRecord không trực tiếp build các câu query bằng cách nối các đoạn string mà tất cả đều dựa trên Abstract Syntax Tree (AST). Mỗi một câu query là một AST bao gồm các node (Arel::Nodes::Note) chứa thông tin của từng query fragment. Sau khi kết hợp các node lại với nhau chúng ta sẽ được một câu query hoàn chỉnh. Và mọi thứ bắt đầu từ đây, ActiveRecord sẽ parse params thành từng phần và tạo các node tương ứng.

Để biết cấu trúc của một node bao gồm những thành phần gì, chúng ta hãy cùng phân thích một query fragment đơn giản sau:

`users`.`id` = ?

Để tạo ra được query fragment trên, sẽ cần một subtree với 3 node. left là node chứa thông tin của column trong khi right đóng vai trò là query placeholder. Chúng tạo thành hai vế của một câu điều kiện. Câu điều kiện đó loại nào sẽ được xác định bởi node cha, ở đây là Arel::Nodes::Equality đại diện là dấu =. Các subtree cũng sẽ được kết hợp với nhau theo cách tương tự.

Query structure

Bây giờ là lúc nhìn vào bức tranh tổng thể để biết cách một câu query hoàn chỉnh được tạo ra. Hãy cùng xem ví dụ sau:

User.where(id: 1)
SELECT `users`.* FROM `users` WHERE `users`.`id` = 1

Và đây là AST tương ứng với câu query trên:

Screen Shot 2023-08-19 at 16.34.10.png

Tất cả các AST đều có cấu trúc tư tự như trên và nó sẽ bao gồm hai phần chính:

  • Select: Là nơi chứa các thông tin liên quan đến select, joins, group, limit, having…
  • Where: Bao gồm các predicates, chúng tạo thành các biểu thức điều kiện sau đó sẽ được kết hợp với các thông tin trong binds để inject values vào query placeholders.

Với các câu query phức tạp, AST cũng trở nên phức tạp hơn nhưng về cấu trúc, nó không có gì khác biệt. Chúng ta hãy cùng xem các ví dụ khác để có cái nhìn chi tiết hơn.

Sử dụng điều kiện or

User.where(id: 1).or(User.where(id: 2))
SELECT `users`.* FROM `users` WHERE (`users`.`id` = 1 OR `users`.`id` = 2)

Screen_Shot_2023-08-19_at_17.14.43.png

Sử dụng group, limithaving

User.where(id: 1).group(:name).having("sign_in_count > 100").limit(10)
SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 GROUP BY `users`.`name` HAVING (sign_in_count > 100) LIMIT 10

Sử dụng điều kiện trong joins

UserCorporation.joins(:corporation).where( user_corporations: { id: 1 }, corporations: { id: 2 }
)
SELECT `user_corporations`.* FROM `user_corporations` INNER JOIN `corporations` ON `corporations`.`id` = `user_corporations`.`corporation_id` WHERE `user_corporations`.`id` = 1 AND `corporations`.`id` = '2'

ActiveRecord sẽ duyệt tree theo chiều từ dưới lên trên cho đến khi có được một câu query hoàn chỉnh. Chi tiết về các node các bạn có thể tham khảo thêm ở đây.

Summary

Vừa rồi chúng ta đã cùng nhau đi tìm hiểu cấu trúc của một AST và cách mà ActiveRecord tạo nên các câu query. Hi vọng nó sẽ mang đến cho bạn cái nhìn chi tiết để từ đó giúp bạn viết và tối ưu query sử dụng ActiveRecord tốt hơn.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tôi cá là bạn không biết những điều này - Ruby on rails ( Phần 2)

Các bạn có thể theo dõi phần 1 ở đây :. https://viblo.asia/p/toi-ca-la-ban-khong-biet-nhung-dieu-nay-ruby-on-rails-phan-1-WAyK8DDeKxX. 5.

0 0 222

- vừa được xem lúc

Rails Memoization

Memoization is a process that can be used to speed up rails methods. It caches the results of methods that do time-consuming work, work that only needs to be done once. Here is an example. Example.

0 0 48

- vừa được xem lúc

Tại sao Rails lại dùng cả Webpack lẫn Sprocket?

Khi Rails 6 được ra mắt, có thể bạn đã từng tự hỏi. WTF, sao Webpack đã được add vào rồi, mà Sprocket vẫn tồn tại thế kia . Chẳng phải Webpack và Sprocket được dùng để giải quyết chung một công việc hay sao. Hoặc cả đây:.

0 0 59

- vừa được xem lúc

Bạn nên sử dụng Elasticsearch trong ứng dụng Ruby On Rails như thế nào?

Elasticsearch là một công cụ phân tích và mã nguồn mở mạnh mẽ và linh hoạt, phân tán, theo thời gian thực. Đó là tiêu chuẩn vàng trong công nghệ tìm kiếm.

0 0 80

- vừa được xem lúc

Form object pattern trong rails

1.Mở đầu.

0 0 111

- vừa được xem lúc

Sử dụng Twilio để gửi SMS trong ứng dụng Ruby on Rails

Ngoài cách xác nhận tài khoản hay gửi thông báo bằng email thì hôm nay mình sẽ hướng dẫn các bạn 1 cách nữa là thông qua SMS/Voice. Công cụ sử dụng sẽ là gem Twilio. Installation. Để cài đặt bằng Bundler, hãy lấy phiên bản mới nhất:.

0 0 67