在Ruby on Rails中查看nil
我已经和Rails一起工作了一段时间,我发现自己经常做的一件事就是在显示之前检查我的视图代码中是否有某些属性或对象为nil。 我开始怀疑这是否总是最好的主意。
到目前为止,我的理由是,由于我的应用程序依赖于用户输入,可能会发生意外情况。 如果我从编程中学到了一件事,那就是用户输入程序员没想到的东西是运行时错误的最大来源之一。 通过检查零值,我希望回避这一点并让我的观点优雅地处理问题。
虽然我通常由于各种原因在我的模型或控制器代码中都有类似的无效或无效的值检查。 我不会在最严格的意义上称它为代码重复,但它似乎并不是很干。 如果我已经在我的控制器中检查了nil对象,那么我的视图只是假设对象真的不是零吗? 对于可以显示为零的属性,每次检查都是有意义的,但对于对象本身,我不确定什么是最佳实践。
这是我正在谈论的简化但典型的例子:
控制器代码
def show @item = Item.find_by_id(params[:id]) @folders = Folder.find(:all, :order => 'display_order') if @item == nil or @item.folder == nil redirect_to(root_url) and return end end
查看代码
display the item's attributes here Oops! Looks like something went horribly wrong!
这是个好主意还是只是愚蠢?
您的示例代码重新制作:
控制器代码。 (我假设这是ItemsController)
def show # This will fail with 404 if item is not found # You can config rails to pretty much render anything on Error 404 @item = Item.find(params[:id]) # doesn't seem to be used in the view # @folders = Folder.find(:all, :order => 'display_order') # this is not needed anymore, or should be in the Error 404 handler #if @item == nil or @item.folder == nil # redirect_to(root_url) and return #end end
查看代码,因为控制器确保我们有@item
#display the item's attributes here <%= item_folder_link(@item) %>
帮助代码:
# display link if the item has a folder def item_folder_link(item) # I assume folder.name should be a non-blank string # You should properly validate this in folder model link_to( item.folder.name, folder_path(item.folder) ) if item.folder end
无论如何,我试着让观点变得非常简单。 通常,如果我在视图中看到循环和条件,我会尝试将它们重构为帮助器。
不,你应该使用
<% if @item.nil? %>
例如
@item1=nil if @item1.nil? ### true @item2 = "" if @item2.nil? ### false @item3 = [] if @item3.nil? ### false @item4 = {} if @item4.nil? ### false
要检查对象是空的,如果它是假,空或空白字符串。
使用
<% if @item.blank? %>
ref: – 这个
例如
@item1=nil if @item1.blank? #### true @item2 = "" if @item2.blank? #### true @item3 = [] if @item3.blank? #### true @item4 = {} if @item4.blank? #### true
不要忘记.try,它是在Rails 2.3中添加的。 这意味着您可以调用以下内容:
@object.try(:name)
如果@object为nil,则不会返回任何内容。 这可能是sameera207理念的内置解决方案。
理想情况下,您不应该将nil对象发送到视图中 – 但是并不总是可以避免。
我个人认为,如果你在你的视图中检查nil
(我认为,因为视图是最终的表示层nil
应该在该级别检查),你不想在控制器中检查它。 (但这并不适用于所有地方)
我建议你创建一个方法来检查nil
(使它变得很干)并传递你的对象并检查它是否为零
就像是:
def is_nil(object) object.nil? ? '':object end
并将其添加到应用程序控制器中并使其成为帮助程序(以便您可以在控制器和视图中使用它)
( helper_method :is_nil
– 将此行添加到应用程序控制器)
现在你可以传递你想要检查的对象是否为零。
干杯,
sameera
您的控制器负责决定要呈现的视图。 如果您可以validation控制器在没有项目或item_folder的情况下永远不会渲染此特定视图,那么您无需检查nil值。
通过可以validation我的意思是你有测试/规格检查为nil项和item_folders呈现哪个视图。