2011-06-29 15 views
5

Tôi đang xây dựng đường mòn kiểm tra cần biết người dùng nào hiện đang thực hiện yêu cầu. Đường mòn kiểm toán của tôi được tạo bằng cách sử dụng ActiveSupport :: Thông báo để nhận ngay cả khi cần phải được kiểm tra.Cách truy cập current_user từ Thông báo Rails?

Điều tôi muốn làm là sử dụng ActiveSupport :: Mối quan tâm để đóng gói logic cho nhu cầu kiểm toán của mình, để tôi có thể dễ dàng thêm kiểm toán vào bất kỳ mô hình nào trong hệ thống của mình.

Nói chung, điều này rất dễ thực hiện. Tôi thậm chí blogged about it a while back. Tuy nhiên, tôi đang gặp khó khăn trong việc tìm ra cách để người dùng hiện tại thực hiện yêu cầu tới máy chủ web, để tôi có thể đăng nhập ai đang thực hiện những thay đổi trong đường dẫn kiểm toán của mình.

Tôi biết có rất nhiều câu hỏi về "làm cách nào để lấy current_user trong mô hình của mình" nhưng tôi không hỏi về cách làm trong mô hình, vì vậy tôi hy vọng có một bộ câu trả lời tốt hơn. Vì mã kiểm tra của tôi có liên quan đến cơ sở hạ tầng, tôi hy vọng rằng có một số cách tôi có thể nhấn vào yêu cầu hiện tại đang được xử lý hoặc một thứ khác chắc chắn sẽ cho tôi biết ai hiện đang đăng nhập/thực hiện yêu cầu.

Tôi đã đọc rất nhiều "câu trả lời" có nghĩa là sử dụng bộ nhớ luồng và đặt current_user vào đó. Tôi không thích câu trả lời này vì nhiều lý do mà những người khác không - không có gì đảm bảo rằng lưu trữ luồng là an toàn. nó có thể tràn qua nhiều yêu cầu nếu máy chủ sử dụng cùng một luồng để xử lý nhiều yêu cầu, v.v.

vì vậy ... cho rằng tôi không cố gắng truy cập current_user từ mô hình của mình, mà là từ ActiveSupport :: Concern hoặc ActiveSupport :: Đăng ký sự kiện thông báo, có bất kỳ tùy chọn tốt nào để tôi biết người dùng hiện tại là ai không?

Cập nhật

Tôi đang sử dụng đưa ra để xác thực, trong đó sử dụng Warden trở lại vào cuối. tìm ra current_user bằng cách gọi request.env['warden'].authenticate(:scope => :user) (giả sử tôi sử dụng mô hình "Người dùng" để xác thực).

Có cách nào để tôi truy cập đối tượng request hiện tại từ trong mối quan tâm hoặc đăng ký thông báo của tôi không? Quay trở lại trong NET ngày của tôi, tôi đã có thể gọi HttpContext.Current.Request và tất cả sẽ là tốt. Tương đương với Rails là gì?

+0

nhờ cho việc sửa chữa liên kết. :) chỉ là về để làm điều đó và thấy bạn đã chăm sóc nó! –

+0

Bạn có tìm thấy giải pháp cho việc này không? Nếu bạn đã làm, xin vui lòng viết về nó. Cảm ơn. – Shreyas

Trả lời

-1

Bạn đã có câu trả lời, những gì bạn đang làm giống như khi mọi người truy cập yêu cầu trong các mô hình. Current_user chỉ là một phương thức được định nghĩa trên ApplicationController của bạn. Khi bạn không ở trong một bộ điều khiển hoặc lớp khác kế thừa từ nó, bạn không thể truy cập phương thức đó.

HttpContext.Current.Request < < Tôi sẽ đặt cược rất nhiều rằng điều này sử dụng lưu trữ luồng. Bất kỳ giải pháp nào khác mà chúng tôi tìm thấy cũng sẽ là lưu trữ chuỗi ở cấp độ nào đó hoặc cấp độ khác.

Hoặc rút ra những gì bạn cần từ yêu cầu trong bộ điều khiển và chuyển nó xuống dưới dạng tham số hoặc sử dụng bộ nhớ luồng - nhưng điều này vốn dĩ vẫn nguy hiểm. Điều gì sẽ xảy ra nếu bạn bắt đầu sử dụng công việc bị trì hoãn để thực hiện các thông báo hoặc điều gì đó?

+0

Biến điều này thành có thể, sử dụng chức năng tường lửa rõ ràng, mà không cần lưu trữ cục bộ luồng, sử dụng 'append_info_to_payload' – cluesque

0

Đường ray 'ActionController::Instrumentation có hỗ trợ rõ ràng cho việc này, sử dụng append_info_to_payload.

Thêm một phương pháp để ApplicationController của bạn:

def append_info_to_payload(payload) 
    super 
    payload[:current_user_id] = current_user.try(&:id) 
end 

bây giờ, khi quan sát viên của bạn được gọi trở lại, các thông tin sẽ được trong event.payload:

ActiveSupport::Notifications.subscribe /process_action.action_controller/ do |*args| 
    event = ActiveSupport::Notifications::Event.new(*args) 
    current_user_id = event.payload[:current_user_id] 
    # do something interesting with current_user_id here 
end