official page有这个片段:
def show
@book = Book.find(params[:id])
if @book.special?
render :action => "special_show" and return
end
render :action => "regular_show"
end
为什么这不等同?
def show
@book = Book.find(params[:id])
if @book.special?
render :action => "special_show"
return
end
render :action => "regular_show"
end
或者,为什么不使用它?
def show
@book = Book.find(params[:id])
if @book.special?
render :action => "special_show" and return
else
render :action => "regular_show"
end
end
我不理解render ... and return
答案 0 :(得分:2)
这是一个非常糟糕的例子。我真的反对and return
短路方法,因为很多人不明白这意味着什么,而且除非你小心注意,否则它很容易被忽视。
更好的方法是描述你有明确if
语句的地方,它突破了两种可能性。我将进一步将此全部折叠为一个render
调用,其中提前确定了action参数:
def show
@book = Book.find(params[:id])
# Determine the template to be used for this action
render_action = @book.special? ? 'special_show' : 'regular_show'
# Render the appropriate template
render(:action => render_action)
rescue ActiveRecord::RecordNotFound
render(:action => 'not_found', :status => :not_found)
end
示例中还缺少find
调用的陷阱,如果找不到记录,则会产生异常。这是一种常见的过度观察,我很确定大多数人完全忘记它。请记住,即使收到错误的请求,您也不应在精心设计的应用中呈现500“服务器错误”。
避免双重渲染错误的最简单方法是,毕竟只能进行一次render
调用。
答案 1 :(得分:1)
他们 实际上都是等同的。你的例子碰巧用最不直观的版本。不知道为什么,但这种风格是我在Rails示例中经常看到的。
基本上,and
是一个布尔运算符,具有非常低的绑定优先级,因此像expression_a and expression_b
这样的行将导致expression_a
被评估,然后,只要它没有评估为nil
或false
,它会评估expression_b
。由于render
返回......好,非错误的东西 - 不知道究竟是什么......你的例子的行为与render whatever; return
完全相同(或者用换行符代替分号,就像在第二个片段。
就个人而言,我更喜欢第三个片段,带有if / else块(不需要and return
),因为无论如何它都在函数的末尾。它显而易见的是它的作用,我喜欢在我的代码中。
希望这有帮助!
答案 2 :(得分:1)
在第一个代码段中,如果and return
不存在,并且@book.special?
是真的,那么您将获得DoubleRenderError
。那是因为render
调用都将被执行。
考虑到这一点,所有的片段都是等效的,因为它们会阻止render
被调用两次。另外,在最后一个片段中,不需要and return
,因为render
中只有一个会被调用。