class SomeController < ApplicationController
before_action :api_limit
def new
if user.can_access_foo?
render 'foo'
end
if user.can_access_bar?
render 'bar'
end
if user.can_access_hello?
render 'hello'
end
end
def api_limit
render 'exceed_limit_error'
# code in action will not be executed.
end
end
在before_filter中存在render
或redirect_to
时,不会执行操作。简而言之,不存在双重渲染的风险。
请参阅Rails Guide on controllers:
如果“之前”过滤器呈现或重定向,则该操作将不会运行。如果计划在该过滤器之后运行其他过滤器,则它们也会被取消。
但是,为什么Rails允许在动作中进行双重渲染?
以下面的代码为例。当用户可以访问foo
,bar
或hello
时,Rails会引发双重渲染异常。
class SomeController < ApplicationController
before_action :callback
def new
if user.can_access_foo?
render 'foo'
# From my understanding, following render should
# be ignored if this step is successfully performed.
end
if user.can_access_bar?
render 'bar'
end
if user.can_access_hello?
render 'hello'
end
end
end
为什么不立即响应并在render 'foo'
完成时停止请求周期?这听起来更合理。
答案 0 :(得分:1)
动作中render
语句没有返回代码执行的原因是,在渲染之后还有一些(非呈现)代码要执行是合理的用例。行动。
before_action
回调中的渲染不允许代码执行进入操作的原因是因为这会假设您的操作具有既不渲染也不重定向的代码路径(否则您会得到双重渲染错误)。操作中的这个代码路径是一个不太合理的用例,因为它依赖于&#34;之前&#34;过滤器已经触发并执行了渲染。
Rails&#39;结构的意图控制器中的动作和过滤器是它们没有紧密耦合的。通常,过滤器不会知道在它之后将运行什么操作,并且操作不知道在它运行之前触发了哪些过滤器。因此,为了使它们协调哪个正在进行渲染会破坏松耦合。每个动作都必须假设渲染是其角色的重要组成部分,这就是为什么如果已经渲染过滤器,则运行动作没有意义。