each
을 사랑합니다. 하지만 문제가 있습니다. 빈 컬렉션이 있으면 어떻게 되나요?
[].each
를 호출하면 , 아무 일도 일어나지 않으며 []
반환됩니다. 때로는 그것이 당신이 원하는 것입니다. 그러나 더 자주, 특히 UI를 빌드할 때 특별한 방법으로 빈 목록을 처리하고 싶을 것입니다. 예를 들어 데이터가 없을 때 일반적으로 다른 메시지를 표시하고 싶습니다.
하지만 [].each
이후로 []
반환 , nil
이 아닙니다. , 다음과 같은 내용을 작성하는 데 문제가 있습니다.
<% if @users.empty? -%>
<p>You don't have any users. <%= link_to "Add one!", new_user_path %></p>
<% else -%>
<% @users.each do |user| -%>
<p><%= user.name %></p>
<% end -%>
<% end -%>
작동하지만 어색하게 느껴집니다. 나는 오히려 "이 컬렉션의 각 항목에 대해 이 작업을 수행합니다. 아무 것도 없는 경우를 제외하고는 다른 작업을 완전히 수행합니다."라고 말하고 싶습니다. each
과 같은 것을 원합니다. , "또는 기타"와 함께.
Rails 컬렉션 렌더링
당신의 관점에서 Rails가 도움이 될 수 있습니다. 컬렉션을 렌더링하는 데 탁월합니다.
<%= render @users %>
<p><%= user.name %></p>
render
할 때 @users
가 전달됨 , _user.html.erb
를 렌더링합니다. @users
내의 각 사용자에 대해 한 번 . each
을 건너뛸 수 있습니다. 완전히.
보너스로 @users
인 경우 비어 있습니다. render
nil
반환 , 우리가 원하는 대로! 따라서 이것을 작성하면 원본 버전과 동일한 출력을 얻을 수 있습니다.
<%= render(@users) || render('empty') %>
<p><%= user.name %></p>
<p>You don't have any users. <%= link_to "Add one!", new_user_path %></p>
Rails의 규칙을 이해하면 훨씬 더 직접적입니다.
보기 외부는 어떻습니까?
Rails를 따르는 경우 render
컬렉션을 사용하는 것은 개체 컬렉션을 렌더링하는 빠르고 강력한 방법입니다.
그러나 때로는 각 항목을 렌더링하기 위해 추가 부분을 처리하고 싶지 않을 때가 있습니다. 또는 render
귀하의 디자인을 지원하지 않습니다. 아니면 뷰 안에 있지도 않을 것입니다.
지금까지 내가 찾은 최고의 솔루션은 presence
입니다. .
list.presence
다음과 동일합니다:
if list.present?
list
else
nil
end
즉, 목록에 항목이 있으면 목록을 다시 가져오고 nil
비어 있는 경우.
presence
, 다음과 같이 작성할 수 있습니다.
@users.each do |user|
puts user.name
end.presence || puts("You don't have any users.")
@users
에 사용자가 있는 경우 각 이름을 인쇄합니다. , 또는 You don't have any users
그렇지 않으면.
그래도 presence
없이는 할 수 있습니다. . 하나이기 때문에 해킹처럼 느껴집니다. 지원되는 경우 다음과 같은 것이 더 나을 수 있습니다.
@users.each do |user|
puts user.name
end || puts("You don't have any users.")
또는 Smalltalk-ish:
@users.each(if_empty: lambda { puts "You don't have any users." }) do |user|
puts user.name
end
또는 심지어 (헉!):
for user in @users
puts user.name
else
puts "You don't have any users."
end
하지만 지금은 보통 presence
를 사용합니다. 또는 기본 if blank?; else each
패턴.
어느 것이 더 낫다고 생각합니까? 빈 목록을 어떻게 처리합니까? 더 나은 방법을 찾았습니까? 그렇다면 알려주세요!