2010-05-01 2 views
12

저는 레일스에서 ​​잠시 동안 작업 해 왔습니다. 끊임없이 제가하고있는 한 가지 일은, 속성이나 객체가 표시되기 전에 어떤 속성이나 객체가 제보기 코드에 nil인지 확인하는 것입니다 . 이것이 항상 최고의 아이디어인지 궁금해지기 시작했습니다.Ruby on Rails의 뷰에서 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 %> 

아니면 그냥이다 바보?

답변

6

귀하의 예제 코드를 다시 만들어 :

컨트롤러 코드. 컨트롤러가 우리가 확신했다 있기 때문에,

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 

보기 코드 (나는이 ItemsController 가정) @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

없음 유우는, 거짓 빈 또는 공백 문자열의 경우 개체가 비어 확인하려면 예를

@item1=nil 
if @item1.nil? ### true 
@item2 = "" 
if @item2.nil? ### false 
@item3 = [] 
if @item3.nil? ### false 
@item4 = {} 
if @item4.nil? ### false 

에 대한

<% if @item.nil? %> 

사용할 수 없습니다.

사용

<% if @item.blank? %> 

REF : - 예를 들어 this

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

컨트롤러는 뷰가 렌더링 될 것입니다 어떤 결정하기위한 책임이 있습니다. 을 확인하면 컨트롤러가 항목 또는 항목 _ 항목이없는 특정보기를 렌더링하지 않을 것이므로 nil 값을 확인할 필요가 없습니다.

은 확인할 수 있습니다. 즉, nil 항목과 item_folders에 대해 어떤보기가 렌더링되는지 검사하는 테스트/사양이 있다는 의미입니다.

0

개인적으로 당신이보기에서 nil을 체크하고 있다면 (그리고 나는 뷰가 비평가적인 표현 레이어이기 때문에 그 레벨에서 nil을 체크해야한다고 생각한다.) 컨트롤러에서 체크하고 싶지 않다.이

뭔가 전무인지 아닌지

나는 (그것을 약간의 DRY를 만들기 위해) 전무를 확인하고 개체를 전달하고 확인하는 방법을 만들 수 추천 할 것입니다 (하지만이 모든 장소에 대해 적용되지 않습니다) like

def is_nil (object) object.nil? ? '': 개체 끝

응용 프로그램 컨트롤러에 추가하고 (당신이 컨트롤러와 뷰 모두에서 사용할 수 있도록) 그것을 도우미을

(helper_method : is_nil - 응용 프로그램에이 줄을 추가 컨트롤러)

이제 nil인지 여부를 확인하려는 개체를 전달할 수 있습니다.

환호, 사 미라

2

레일즈 2.3에 추가 된 .try를 잊지 마세요. 즉, 다음과 같이 호출 할 수 있습니다.

@object.try(:name) 

그리고 @object가 nil 인 경우 아무 것도 반환되지 않습니다. 이것은 아마도 sameera207의 아이디어를위한 내장 된 솔루션 일 것입니다.

이상적으로는 뷰에 아무 것도 보내지 않아야하지만, 항상 피할 수있는 것은 아닙니다.