Ruby on rails 在RubyonRails中检查视图中的nil

Ruby on rails 在RubyonRails中检查视图中的nil,ruby-on-rails,error-handling,Ruby On Rails,Error Handling,我使用Rails已经有一段时间了,我发现自己经常做的一件事是在显示视图代码之前检查某些属性或对象是否为nil。我开始怀疑这是否总是最好的主意 到目前为止,我的理由是,由于我的应用程序依赖于用户输入,因此可能会发生意外情况。如果我从编程中学到一件事,那就是用户输入程序员没有想到的东西是运行时错误的最大来源之一。通过检查nil值,我希望避开这个问题,让我的观点优雅地处理这个问题 问题是,由于各种原因,我通常会在模型或控制器代码中进行类似的nil或无效值检查。严格来说,我不会称之为代码复制,但它似乎并

我使用Rails已经有一段时间了,我发现自己经常做的一件事是在显示视图代码之前检查某些属性或对象是否为nil。我开始怀疑这是否总是最好的主意

到目前为止,我的理由是,由于我的应用程序依赖于用户输入,因此可能会发生意外情况。如果我从编程中学到一件事,那就是用户输入程序员没有想到的东西是运行时错误的最大来源之一。通过检查nil值,我希望避开这个问题,让我的观点优雅地处理这个问题

问题是,由于各种原因,我通常会在模型或控制器代码中进行类似的nil或无效值检查。严格来说,我不会称之为代码复制,但它似乎并不十分枯燥。如果我已经在我的控制器中检查了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
视图代码

<% if @item != nil %>
    display the item's attributes here

    <% if @item.folder != nil %>
        <%= link_to @item.folder.name, folder_path(@item.folder) %>
    <% end %>
<% else %>
    Oops! Looks like something went horribly wrong!
<% end %>

在此处显示项目的属性
哎呀!看起来好像出了什么大问题!
这是个好主意还是很傻?

不,你应该使用

<% if @item.nil? %>
如果对象为false、空或空白字符串,则检查该对象是否为空

使用


控制器负责决定要渲染哪个视图。如果可以验证控制器在没有项目或项目\文件夹的情况下不会呈现此特定视图,则无需检查nil值


通过can verify,我的意思是你有测试/规格来检查为nil项和item_文件夹呈现的视图。

我个人认为,如果你在视图中检查
nil
(我认为既然视图是最终的表示层,那么应该在该级别检查
nil
),您不想在控制器中检查它。(但这并不适用于所有地方)

我建议您创建一个方法来检查
nil
(使其稍微干燥),并传递您的对象并检查它是否为nil

比如:

def is_nil(object)
 object.nil? ? '':object 
end 
并将其添加到应用程序控制器中,使其成为助手(以便您可以在控制器和视图中使用它)

helper\u方法:is\u nil
-将此行添加到应用程序控制器)

现在您可以传递要检查的对象,它是否为零

干杯


sameera

重新生成示例代码:

控制器代码。(我假设这是ItemsController)

查看代码,因为控制器确保我们有@item

#display the item's attributes here

<%= item_folder_link(@item) %>

不管怎样,我尽量使视图非常简单。通常,如果我在视图中看到循环和条件,我会尝试将它们重构为帮助程序。

别忘了。try,它是Rails 2.3中添加的。这意味着您可以调用如下内容:

@object.try(:name)
如果@object为nil,则不会返回任何内容。这可能是sameera207想法的内置解决方案

理想情况下,您不应该将nil对象发送到视图,但是这并不总是可以避免的

def is_nil(object)
 object.nil? ? '':object 
end 
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
#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
@object.try(:name)