2010-05-01 25 views
12

我一直在使用Rails一段时间,我发现自己经常在做的一件事是在我显示它之前检查一下某个属性或对象是否在我的视图代码中为零。我开始怀疑这是否是最好的想法。在Ruby on 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 

视图代码

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

这是一个好主意,或者是它只是愚蠢?

回答

6

你的示例代码重拍:

控制器代码。 (我想这是上述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

无悠应该使用

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

你的控制器负责决定哪些观点将被渲染。如果你可以验证你的控制器将永远不会渲染这个没有item或item_folder的特定视图,那么你不需要检查nil值。

通过可以验证我的意思是你有测试/规格,检查哪些视图呈现为零项和item_folders。

0

我个人认为如果你在你的视图中检查nil(我认为自从视图是非关系表示层nil应该在该级别检查),你不想在控制器中检查它。(但这并不适用于所有的地方)

我会建议你创建一个方法来检查零(使它有点干),并通过你的对象,并检查它是否是零或不

东西像

def is_nil(object) object.nil? ? “”:对象 结束

,并将其添加在应用程序控制器,并使其成为辅助(这样就可以在两个控制器和视图使用它)

(是helper_method:is_nil - 这行添加到您的应用程序控制器)

现在你可以传递你想检查的对象是否为零。

欢呼声, sameera

2

不要忘了.try,它是在Rails 2.3中添加的。这意味着您可以拨打以下内容:

@object.try(:name) 

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

理想情况下,您不应该通过发送零对象到视图 - 但它并不总是可以避免的。