Rails Params: chúng đến từ đâu ?
Bài đăng này đã không được cập nhật trong 4 năm
Rack
Để hiểu cách Rails diễn giải params, bạn sẽ phải hiểu những điều cơ bản của Rack và cách Rails tương tác với nó. Theo document của rack:
Rack provides a minimal interface between web servers that support Ruby and Ruby frameworks. To use Rack, provide an “app”: an object that responds to the call method, taking the environment hash as a parameter, and returning an Array with three elements:
- The HTTP response code
- A Hash of headers
- The response body, which must respond to each
Về cơ bản thì Rack sẽ nằm giữa web server và ứng dụng Rails của bạn.
- Nó nhận request từ web server, chuyển nó thành biến
env
(Ruby hash) mà Rails có thể hiểu - Rails lấy biến
env
đó, thực hiện những gì nó cần với nó và trả về một mảng đơn giản trở lại Rack vớiHTTP response code
,headers
vàresponse body
. - Rack lấy mảng đó, chuyển nó trở lại thành phản hồi HTTP thích hợp và đưa nó đến trình duyệt để hiển thị.!
“params” là gì ?
Để hiểu rõ hơn về việc params bắt nguồn từ đâu, chúng ta cần hiểu rõ hơn về nó. Có phải là một Hash
? Method
? Thứ gì khác ?
Cách tốt nhất để tìm ra điều này là đặt binding.pry
vào một controller action
và cố gắng tìm hiểu xem nó có những cái gì.
Hãy lấy 1 VD:
Sau khi submit 1 test form
Tiếp tục tìm hiểu:
params
là một method của lớpActionController::StrongParameter
.- Mặc dù
params
được thể hiện như là mộthash
, nhưng thữ ra nó là một instance của lớpActionControll::Paramameter
.
Nếu bạn không quen thuộc với ActionControll::StrongParameter
, thì đây là lớp cấp cho chúng ta nhiều bảo mật hơn và dùng để hạn chế đối với tham số đầu vào. Nếu bạn đã từng sử dụng cú pháp này trước đây, bạn có thể cảm ơn ActionContoder::StrongParameter
:
params.require(:post).permit!
Bên trong source code ActionControll::StrongParameter
, bạn sẽ tìm thấy params
trong đó.
Như bạn thấy, params
là một getter method của lớp ActionContoder::StrongParameter
và nó trả về biến instance @_params
, là một instance của lớp ActionContoder::Paramameter
.
Thoạt nhìn, điều này có vẻ không có ích nhiều, nhưng điều này giải thích tại sao params
có sẵn cho chúng ta trong controller của chúng ta. Kiểm tra console của bạn sẽ cho bạn biết lý do tại sao.
Chúng ta có quyền truy cập vào params
vì controller của chúng ta là descendants
của ActionContoder::StrongParameter
và kế thừa tất cả các instance methods
của nó!
Trong khi điều này giải thích bí ẩn params
có mặt ở khắp nơi, thì nó không giải thích làm thế nào nó để có được nó. Nếu bạn như tôi, bạn muốn biết toàn bộ câu chuyện. Ví dụ, request.parameters là gì? Nó đến từ đâu?
params
đến từ đâu
Sau khi tìm hiểu nhiều hơn về Rails, tôi đã thấy ActionControll::Metal
. Về cơ bản, ActionControll::Metal
là một phiên bản khung xương
của ActionControll::Base
.
Nếu bạn nhìn vào source code của nó, bạn sẽ tìm thấy một số tài liệu liên quan đến request
cũng như tập hợp các methods liên quan đến params
.
Tại thời điểm này tôi nên đề cập rằng, để đi sâu hơn vào Rails, tôi đã bao gồm một trình ghi stack trace.
Lý do tôi đề cập đến điều này là bởi vì bạn sẽ thấy tất cả các methods được gọi khi Rails nhận được một biến env từ Rack - và có RẤT NHIỀU. Nếu bạn muốn xem mọi thứ xảy ra đằng sau hậu trường, hãy xem cái này.
Mặc dù nhật ký này rất ấn tượng và quái dị, nhưng chỉ có một vài dòng mà chúng ta cần phải lo lắng về params
và ActionContoder::Metal
.
Các dòng có liên quan được tô màu xanh lam
ActionController::Metal#dispatch
ActionController::Metal::action
Điều mà stack trace này nói là sau khi Rails được khởi tạo với biến env, biến đó được truyền qua Rails. Tại một số điểm, nó hướng tới class method ActionControll::Metal::action
. Bên trong phương thức này, ActionContoder::Metal
khởi tạo một instance
mới của chính nó và gọi #dispatch
, nó đặt @_request
là một instance
mới của lớp ActionDispatch:: Request
.
ActionDispatch::Request
là giao diện Rails sử dụng để tương tác với HTTP request
(env) có nguồn gốc từ Rack. Một trong những phương thức mà API này cung cấp là #parameters
.
Đây là khởi nguồn của request.parameter
!
All rights reserved