2012-04-09 4 views
5

Có cách nào tôi có thể chuyển đối số cho cuộc gọi hành động điều khiển từ phần mềm trung gian không?gọi hành động điều khiển với đối số từ giá trung gian

Đây là hành động trong mã điều khiển

# in my_controller.rb 
# 
def print_name(name) 
    render :text => "Hello, #{name}!" 
end 

Dưới đây là các mã từ middleware của tôi mà các cuộc gọi hành động này

# in middleware 
# 
def call(env) 
    env['action_controller.instance'].class.action(:print_name).call(env) 
end 

Điều này tất nhiên làm tăng ArgumentError.

Tôi không biết làm cách nào để chuyển đối số cho cuộc gọi action. Đây là nguồn:

# in action_pack/lib/action_controller/metal.rb 
# 
def self.action(name, klass = ActionDispatch::Request) 
     middleware_stack.build(name.to_s) do |env| 
     new.dispatch(name, klass.new(env)) 
     end 
end 

Như bạn có thể thấy, nó trả về điểm cuối giá từ hành động bộ điều khiển được cung cấp. Tôi thấy không có cách nào tôi có thể vượt qua một cuộc tranh luận ở đây.

Tôi đã tự động thay đổi bộ điều khiển bằng class_eval và sau đó gọi phương thức bộ điều khiển từ phương thức proxy đó.

# in middleware 
# 
def define_proxy_method(klass) 
     klass.class_eval do 
      def call_the_real_method 
       print_name(request.env['fake_attribute']) 
      end 
     end 
end 

def call(env) 
    define_proxy_method(env['action_controller.instance'].class) 
    env['fake_attrbute'] = "Yukihiro" 
    env['action_controller.instance'].class.action(:call_the_real_method).call(env) 
end 

Điều này có vẻ bẩn và tôi muốn biết một cách tốt hơn. Cảm ơn.

+1

Có là đã nhận được một cách tiếp cận tốt hơn để bất cứ điều gì bạn cố gắng làm. Nếu bạn có thể cung cấp thêm ngữ cảnh cho những gì bạn đang cố gắng hoàn thành, có thể là một giải pháp ít tốn kém hơn nhiều. –

+0

Tôi đang cố gắng chuyển hướng đến một hành động điều khiển cụ thể sau khi ngoại lệ đã được ném. Về cơ bản nó là một [sửa] (https://github.com/airbrake/airbrake/commit/e13041bf9c69527b9bb34043617e52b6c7615657) cho đá quý airbrake. Thật khó để tìm ra ví dụ về việc gọi phương thức điều khiển từ phần mềm trung gian. Cảm ơn cho bình luận, mặc dù. – shime

Trả lời

4

Bạn không muốn đặt tranh luận về hành động của mình. Middleware chỉ nên tương tác với môi trường yêu cầu, không cố gắng gọi trực tiếp vào bộ điều khiển.

Bạn có thể vượt qua giá trị như nhau trong băm params:

# middleware 
# 
def call(env) 
    request = Rack::Request.new(env) 
    request['name'] = get_name 
end 

và đọc từ băm params trong bộ điều khiển:

# my_controller.rb 
# 
def print_name 
    render :text => "Hello, #{params['name']}!" 
end 
+0

vâng, tôi nhận thấy đó là cách làm sai. nó đã được thực hiện như thế này cho rails 2.x, vì nó có 'rescue_action_in_public (exception)' trong 'ActionController' được định nghĩa, và phương thức này là aliasing nó. Tôi đã cố gắng để thực hiện các hành vi tương tự cho đường ray 3.x, mà không thay đổi cuộc gọi phương thức. cảm ơn cho câu trả lời của bạn mặc dù -> chấp nhận, upvote và tiền thưởng :) – shime

+0

Cảm ơn. Bạn có thể gửi email cho tôi tại winfield.peterson trên gmail hoặc gchat để nói thêm. Bạn có thể trích xuất xử lý/báo cáo ngoại lệ của bạn thành một lớp trợ giúp và sử dụng nó trong cả Middleware và Controllers. Nếu nó có logic chuyển hướng điều khiển cụ thể hoặc những thứ khác bạn có thể đặt trong một khối? Hạnh phúc để đóng vòng lặp trên một giải pháp hoàn chỉnh. – Winfield