在 Ruby on Rails 中检查视图中的 nil

Posted

技术标签:

【中文标题】在 Ruby on Rails 中检查视图中的 nil【英文标题】:Checking for nil in view in Ruby on Rails 【发布时间】:2011-02-14 12:05:09 【问题描述】:

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

到目前为止,我的理由是,由于我的应用程序依赖于用户输入,因此可能会发生意外的事情。如果我从编程中学到了一件事,那就是用户输入程序员没有想到的东西是运行时错误的最大来源之一。通过检查 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 %>

这是个好主意还是很傻?

【问题讨论】:

【参考方案1】:

不,你应该使用

<% 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? %>

参考:-this

例如

@item1=nil
if @item1.blank? #### true
@item2 = ""
if @item2.blank? #### true
@item3 = []
if @item3.blank? #### true
@item4 = 
if @item4.blank? #### true

【讨论】:

【参考方案2】:

您的控制器负责决定要呈现哪个视图。如果您可以验证您的控制器永远不会在没有 item 或 item_folder 的情况下呈现此特定视图,那么您不需要检查 nil 值。

可以验证我的意思是您有测试/规范来检查为 nil 项和 item_folders 呈现哪个视图。

【讨论】:

【参考方案3】:

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

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

类似:

def is_nil(object)
 object.nil? ? '':object 
end 

并将其添加到应用程序控制器中并使其成为助手(以便您可以在控制器和视图中使用它)

helper_method :is_nil - 将此行添加到您的应用程序控制器)

现在你可以传递你想要检查它是否为 nil 的对象了。

干杯,

同样的

【讨论】:

【参考方案4】:

您的示例代码重做:

控制器代码。 (我假设这是 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

无论如何,我尽量保持视图非常非常简单。通常,如果我在视图中看到循环和条件,我会尝试将它们重构为帮助程序。

【讨论】:

【参考方案5】:

不要忘记 .try,它是在 Rails 2.3 中添加的。这意味着您可以调用如下内容:

@object.try(:name)

如果@object 为nil,则不会返回任何内容。这也许是sameera207的想法的内置解决方案。

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

【讨论】:

以上是关于在 Ruby on Rails 中检查视图中的 nil的主要内容,如果未能解决你的问题,请参考以下文章

如何改进 Ruby on Rails 视图中的代码

Ruby on Rails 使用视图助手中的变量在视图中动态生成字段名称

保存到数据库帖子,但在检查 Ruby on Rails 中的 http 请求之前

Ruby On Rails 部分渲染

如何检查特定属性是不是是有效的 ruby​​ on rails

Ruby on Rails - Ruby 中的 KeyCode [关闭]