2010-01-19 67 views
3

任何人都可以解釋render()來自哪裏 ActionController :: Base?rails 3.0:ActionController :: Base render()

我設法跟蹤它向下僅遠:

的ActionController ::基地包括的Act​​ionController ::渲染模塊,其中 render()方法被定義。然而,這個定義要求render() 超類。超類是ActionController :: Metal。其中的 轉從AbstractController :: Base繼承。這些都沒有定義或包含 ()。

現在,大概它來自AbstractController :: Rendering,但是我很難忽略它的包含方式。

+1

@artemave,你問18個問題,並只接受了其中的四個答案。如果答案對你有幫助,那麼請接受它。謝謝! – 2010-01-19 15:51:13

回答

8

您在動作中調用的render方法在ActionController::Base中定義。

def render(action = nil, options = {}, &blk) 
    options = _normalize_options(action, options, &blk) 
    super(options) 
end 

該方法轉到它調用在ActionController::Rendering定義的render方法調用super

def render(options) 
    super 
    self.content_type ||= options[:_template].mime_type.to_s 
    response_body 
end 

ActionController::Rendering實際上是一個模塊,在base.rb文件的開頭混入的ActionController :: Base類。

include ActionController::Redirecting 
include ActionController::Rendering # <-- 
include ActionController::Renderers::All 

在轉彎,ActionController::Rendering包括AbstractController::Rendering,你可以在ActionController::Rendering模塊定義見。

module ActionController 
    module Rendering 
    extend ActiveSupport::Concern 

    included do 
     include AbstractController::Rendering 
     include AbstractController::LocalizedCache 
    end 

AbstractController::Rendering提供render方法,該方法是在渲染調用鏈的最後方法。

# Mostly abstracts the fact that calling render twice is a DoubleRenderError. 
# Delegates render_to_body and sticks the result in self.response_body. 
def render(*args) 
    if response_body 
    raise AbstractController::DoubleRenderError, "Can only render or redirect once per action" 
    end 

    self.response_body = render_to_body(*args) 
end 

上滿鏈是

AbstractController::Base#render 
--> super() 
--> ActionController::Rendering#render 
--> super() 
--> AbstractController::Rendering#render 
--> render_to_body 
+0

「在當前類的超類中超級調用與當前類名稱相同的方法」ActionController :: Rendering不是ActionController :: Base的父類。它是包含模塊。那麼超級怎麼能按照你描述的方式工作呢? – artemave 2010-01-19 18:11:16

+1

當A類包含模塊B時,B成爲A的祖先。請參閱'對象#祖先'。當你在A中調用'super'時,它會在類A的所有祖先中搜索一個具有相同名稱的方法,包括B.在Ruby中,可以通過繼承和/或使用混合來擴展一個類。 – 2010-01-19 18:23:00

+0

這當然是一天中的一個難題。 – artemave 2010-01-19 19:00:43

0

renderAbstractController::Rendering中定義。它調用render_to_body,然後調度到其他方法。這是一個兔子洞,不是嗎?

+0

我不明白這是如何回答原來的問題。 – artemave 2010-01-19 16:16:16

相關問題