2011-10-14 62 views
4

我想從模型中派發(路由和渲染)。 (我只在乎GET請求,我不理Accept:頭,所以我只能看着PATH_INFO。)如何從Rails中的模型路由和渲染(調度)3

# app/models/response.rb 
class Response < ActiveRecord::Base 
    # col :path_info 
    # col :app_version 
    # col :body, :type => :text 

    def set_body 
    params = Rails.application.routes.recognize_path(path_info, :method => :get) 
    controller = "#{params[:controller].camelcase}Controller".constantize.new 
    controller.action_name = params[:action] 
    controller.request = ActionDispatch::Request.new('rack.input' => []) 
    controller.request.path_parameters = params.with_indifferent_access 
    controller.request.format = params[:format] || 'html' 
    controller.response = ActionDispatch::Response.new 
    controller.send params[:action] 
    self.body = controller.response.body 
    end 
end 

上面的代碼工作,但感覺笨重。什麼是正確的做法?我想象Yehuda Katz會告訴我是這樣的:

def set_body 
    # [...] 
    app = "#{params[:controller].camelcase}Controller".constantize.action(params[:action]) 
    app.process params 
    self.body = app.response.body 
end 

FWIW這裏是我的路線文件:

# config/routes.rb 
MyApp::Application.routes.draw do 
    resources :products          # GET /products.json?merchant_id=foobar 
    match '/:id(.:format)' => 'contents#show', :via => 'get' # GET /examples 
    root :to => 'contents#index', :via => 'get'    # GET/
end 

參見:Rails 3 request dispatch cycle

回答

8

它實際上比這更簡單:

session = ActionDispatch::Integration::Session.new(Rails.application) 
session.get(path_info) 
self.body = session.response.body