2010-05-01 2 views
12

Я работаю с Rails какое-то время, и одна вещь, которую я постоянно нахожу, это проверить, не обнаружен ли какой-либо атрибут или объект в моем коде просмотра, прежде чем я его покажу , Я начинаю задаваться вопросом, всегда ли это лучшая идея.Проверка на наличие nil в Ruby on Rails

Мое обоснование до сих пор заключалось в том, что, поскольку мое приложение (ы) полагаются на ввод пользователя, могут возникнуть непредвиденные ситуации. Если я вообще научился программировать, то, что пользователи, вводящие вещи, о которых программист не думал, являются одним из самых больших источников ошибок во время выполнения. Проверяя значения nil, я надеялся обойти это, и мои взгляды изящно справляются с этой проблемой.

Дело в том, что, как правило, по разным причинам имеют аналогичные ошибки nil или invalid в моей модели или коде контроллера. Я бы не назвал это дублированием кода в строгом смысле слова, но он просто не кажется очень сухим. Если я уже проверил для 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

Нет Yuu не следует использовать

<% 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_folder, вам не нужно проверять значения nil.

К может подтвердить Я имею в виду, что у вас есть тесты/спецификации, которые проверяют, какой вид визуализируется для элементов nil и item_folders.

0

Я лично считаю, что если вы проверяете нуль в своих представлениях (и я думаю, что, поскольку представление - это нечетный уровень представления, то nil должен быть проверен на этом уровне), вы не хотите проверять его в контроллере.(Но это не будет применяться для всех мест)

Я бы порекомендовал вам создать метод, чтобы проверить ноль (чтобы сделать его немного DRY) и передать свой объект и проверить, если он равен нулю или не

что-то подобный

def is_nil (объект) объект.nil? ? «»: Объект конец

и добавьте его в контроллер приложения и сделать его помощник (так что вы можете использовать его в обоих контроллеров и представлений)

(helper_method: is_nil - добавьте эту строку в приложение контроллер)

и теперь вы можете передать объект, который хотите проверить, является ли он ником или нет.

веселит, Sameera

2

Не забывайте .try, который был добавлен в Rails 2.3. Это означает, что вы можете назвать что-то вроде следующего:

@object.try(:name) 

И если @object равна нулю, то ничего не будет возвращено. Возможно, это встроенное решение для идеи sameera207.

В идеале вы не должны посылать нильские объекты в представление - однако этого избежать не всегда можно.

Смежные вопросы