Tránh Viết SQL Khi Sử dụng ActiveRelation

ActiveRelation, công cụ tìm kiếm và truy vấn của ActiveRecord, là một công cụ mạnh mẽ và linh hoạt.

Thay vì...

... viết 1 chuỗi SQL trực tiếp vào bên trong ActiveRelation#where

Person.where("name = #{ params[:name] } AND hidden_at IS NULL")

Hoặc

... viết 1 chuỗi SQL và sử dụng 'array style' để đảm bảo an toàn dữ liệu vào

Person.where('name = ? AND hidden_at IS NULL', params[:name])

Sử dụng

... cú pháp 'hash style'

Person.where(name: params[:name], hidden_at: nil)

Tại sao?

Hai phiên bản đầu tiên của Rails, tự viết SQL là những cách duy nhất để xác định truy vấn cơ sở dữ liệu trước khi ActiveRelation được hợp nhất vào Rails (trong phiên bản 3.0). Tuy nhiên, "hash style" cho phép bạn linh hoạt và an toàn hơn.

Ví dụ đầu tiên là rất nguy hiểm. Nó truyển trực tiếp 1 chuỗi SQL, trong trường hợp này các tham số của người dùng được thông qua. Không sử dụng kiểu này vì nó sẽ mở ra cho bạn các cuộc tấn công SQL injection: những người xấu từ Internet có thể thử và chạy các câu lệnh phá hoại cơ sở dữ liệu của bạn.

Ví dụ thứ hai, sử dụng 'array style', dữ liệu thông qua được làm sạch, do đó nó là một cách tốt hơn để viết "string style". Tuy nhiên vẫn còn sót đoạn SQL do bạn viết ra.

Ví dụ cuối cùng, sử dụng 'hash style', ngắn hơn, rõ ràng hơn và dễ dàng chỉnh sửa hơn.

# Hash style
> Person.where(name: 'Andy', hidden_at: nil).to_sql
=> "SELECT \"people\".* FROM \"people\" WHERE \"people\".\"name\" = 'Andy' AND \"people\".\"hidden_at\" IS NULL"

# String style
> Person.where('name = ? and hidden_at is null', 'Andy').to_sql
=> "SELECT \"people\".* FROM \"people\" WHERE (name = 'Andy' and hidden_at is null)"

Khi sử dụng 'hash style', nó bao gồm tên các bảng trong cơ sở dữ liệu và truy vấn SQL chính xác hơn, có thể giúp giảm bớt các lỗi khi truy vẫn.

Sử dụng 'hash style' cũng cung cấp thêm sự thuận tiện trong việc tạo ra các truy vẫn SQL