在Ruby on Rails中查看nil

sea*_*ugh 13 error-handling ruby-on-rails

我已经和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
Run Code Online (Sandbox Code Playgroud)

查看代码

<% 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 %>
Run Code Online (Sandbox Code Playgroud)

这是个好主意还是只是愚蠢?

Aar*_*ian 7

您的示例代码重新制作:

控制器代码.(我假设这是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
Run Code Online (Sandbox Code Playgroud)

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

#display the item's attributes here

<%= item_folder_link(@item) %>
Run Code Online (Sandbox Code Playgroud)

帮助代码:

# 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
Run Code Online (Sandbox Code Playgroud)

无论如何,我试着让视图非常简单.通常,如果我在视图中看到循环和条件,我会尝试将它们重构为帮助器.


Sal*_*lil 6

不,你应该使用

<% if @item.nil? %>
Run Code Online (Sandbox Code Playgroud)

例如

@item1=nil
if @item1.nil? ### true
@item2 = ""
if @item2.nil? ### false
@item3 = []
if @item3.nil? ### false
@item4 = {}
if @item4.nil? ### false
Run Code Online (Sandbox Code Playgroud)

要检查对象是空的,如果它是假,空或空白字符串.

使用

<% if @item.blank? %>
Run Code Online (Sandbox Code Playgroud)

ref: - 这个

例如

@item1=nil
if @item1.blank? #### true
@item2 = ""
if @item2.blank? #### true
@item3 = []
if @item3.blank? #### true
@item4 = {}
if @item4.blank? #### true
Run Code Online (Sandbox Code Playgroud)