Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

각각... 또는 기타

each을 사랑합니다. 하지만 문제가 있습니다. 빈 컬렉션이 있으면 어떻게 되나요?

[].each를 호출하면 , 아무 일도 일어나지 않으며 [] 반환됩니다. 때로는 그것이 당신이 원하는 것입니다. 그러나 더 자주, 특히 UI를 빌드할 때 특별한 방법으로 빈 목록을 처리하고 싶을 것입니다. 예를 들어 데이터가 없을 때 일반적으로 다른 메시지를 표시하고 싶습니다.

하지만 [].each 이후로 [] 반환 , nil이 아닙니다. , 다음과 같은 내용을 작성하는 데 문제가 있습니다.

app/views/users/index.html.erb
<% 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가 도움이 될 수 있습니다. 컬렉션을 렌더링하는 데 탁월합니다.

app/views/users/index.html.erb
<%= render @users %>
app/views/users/_user.html.erb
<p><%= user.name %></p>

render할 때 @users가 전달됨 , _user.html.erb를 렌더링합니다. @users 내의 각 사용자에 대해 한 번 . each을 건너뛸 수 있습니다. 완전히.

보너스로 @users인 경우 비어 있습니다. render nil 반환 , 우리가 원하는 대로! 따라서 이것을 작성하면 원본 버전과 동일한 출력을 얻을 수 있습니다.

app/views/users/index.html.erb
<%= render(@users) || render('empty') %>
app/views/users/_user.html.erb
<p><%= user.name %></p>
app/views/users/_empty.html.erb
<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 패턴.

어느 것이 더 낫다고 생각합니까? 빈 목록을 어떻게 처리합니까? 더 나은 방법을 찾았습니까? 그렇다면 알려주세요!