Rails : 데이터베이스에 요소가 없을 때 메시지를 표시하는 우아한 방법
이 코드와 비슷한 코드를 많이 작성하고 있다는 것을 깨달았습니다.
<% unless @messages.blank? %>
<% @messages.each do |message| %>
<%# code or partial to display the message %>
<% end %>
<% else %>
You have no messages.
<% end %>
Ruby 및 / 또는 Rails에 첫 번째 조건을 건너 뛸 수있는 구조가 있습니까? 반복자 / 루프가 한 번도 들어 가지 않을 때 실행됩니까? 예를 들면 :
<% @messages.each do |message| %>
<%# code or partial to display the message %>
<% and_if_it_was_blank %>
You have no messages.
<% end %>
:collection
예 render :partial => 'message', :collection => @messages
를 들어 매개 변수를 사용하여 렌더링 nil
하면 컬렉션이 비어 있으면 render 호출이 반환 됩니다. 그런 다음 || 표현 예
<%= render(:partial => 'message', :collection => @messages) || 'You have no messages' %>
이전에 본 적이없는 경우 렌더링 :collection
은 각 요소에 대해 동일한 부분을 사용하여 컬렉션을 렌더링 하여 전체 응답을 구축 할 때 @messages
지역 변수 message
를 통해 각 요소를 사용할 수 있도록합니다 . 다음을 사용하여 각 요소 사이에 렌더링 할 구분선을 지정할 수도 있습니다.:spacer_template => "message_divider"
다음과 같이 작성할 수도 있습니다.
<% if @messages.each do |message| %>
<%# code or partial to display the message %>
<% end.empty? %>
You have no messages.
<% end %>
제가 가장 좋아하는 답변이 여기에 없다는 것이 놀랍습니다. 가까운 답변이 있지만 맨 텍스트가 마음에 들지 않으며 content_for를 사용하는 것은 klunky입니다. 크기를 위해 이것을 시도하십시오 :
<%= render(@user.recipes) || content_tag("p") do %>
This user hasn't added any recipes yet!
<% end %>
한 가지 방법은 다음과 같이하는 것입니다.
<%= render(:partial => @messages) || render('no_messages') %>
편집하다:
내가 올바르게 기억한다면 이것은이 커밋으로 가능했습니다.
http://github.com/rails/rails/commit/a8ece12fe2ac7838407954453e0d31af6186a5db
사용자 지정 도우미를 만들 수 있습니다. 다음은 예시 일뿐입니다.
# application_helper.html.erb
def unless_empty(collection, message = "You have no messages", &block)
if collection.empty?
concat(message)
else
concat(capture(&block))
end
end
# view.html.erb
<% unless_empty @messages do %>
<%# code or partial to dispaly the message %>
<% end %>
As a note, you may as well just iterate over an empty array if you're looking for efficiency of expression:
<% @messages.each do |message| %>
<%# code or partial to dispaly the message %>
<% end %>
<% if (@messages.blank?) %>
You have no messages.
<% end %>
While this does not handle @messages being nil, it should work for most situations. Introducing irregular extensions to what should be a routine view is probably complicating an otherwise simple thing.
What might be a better approach is to define a partial and a helper to render "empty" sections if these are reasonably complex:
<% render_each(:message) do |message| %>
<%# code or partial to dispaly the message %>
<% end %>
# common/empty/_messages.erb
You have no messages.
Where you might define this as:
def render_each(item, &block)
plural = "#{item.to_s.pluralize}"
items = instance_variable_get("@#{plural}")
if (items.blank?)
render(:partial => "common/empty/#{plural}")
else
items.each(&block)
end
end
Old topic but I didn't really like any of these so playing around on Rails 3.2 I figured out this alternative:
<% content_for :no_messages do %>
<p>
<strong>No Messages Found</strong>
</p>
<% end %>
<%= render @messages || content_for(:no_messages) %>
Or if you need a more verbose render with partial path like I did:
<%= render(:partial => 'messages',
:collection => @user.messages) || content_for(:no_messages) %>
This way you can style the "no messages" part with whatever HTML / view logic you want and keep it nice a easy to read.
That code can be shortened to:
<%= @messages.empty? ? 'You have no messages.' : @messages.collect { |msg| formatted_msg(msg) }.join(msg_delimiter) %>
Comments:
formatted_msg() - helper method which adds formatting to the message
msg_delimiter - variable containing delimiter like "\n" or "<br />
"
BTW I'd suggest to use empty? method instead of blank? for checking an array, because a) its name is more concise :) and b) blank? is an ActiveSupport extension method which won't work outside Rails.
You could split up your two cases into different templates: one if messages exist and one if no message exist. In the controller action (MessagesController#index
probably), add as the last statement:
render :action => 'index_empty' if @messages.blank?
If there are no messages, it'll display app/views/messages/index_empty.html.erb
. If there are messages, it'll fall through and display app/views/messages/index.html.erb
as usual.
If you need this in more than just one action, you can nicely refactor it into a helper method like the following (untested):
def render_action_or_empty (collection, options = {})
template = params[:template] || "#{params[:controller]}/#{params[:action]}"
template << '_empty' if collection.blank?
render options.reverse_merge { :template => template }
end
With this, you just need to put render_action_or_empty(@var)
at the end of any controller action and it'll display either the 'action' template or the 'action_empty' template if your collection is empty. It should also be easy to make this work with partials instead of action templates.
Below solution works for me because I want tr
and td
with colspan
property:
<%= render(@audit_logs) || content_tag(:tr, content_tag(:td, 'No records',colspan: "11"))%>
'Program Tip' 카테고리의 다른 글
문자열에서 부분 문자열 추출 (0) | 2020.11.12 |
---|---|
0.-5가 -5로 평가되는 이유는 무엇입니까? (0) | 2020.11.12 |
더미 변수 생성 (0) | 2020.11.12 |
Twitter Bootstrap 버튼 클릭하여 버튼 위의 텍스트 섹션 확장 / 축소 전환 (0) | 2020.11.12 |
.NET에서 숫자에 대한 "st", "nd", "rd"및 "th"엔딩을 쉽게 얻을 수있는 방법이 있습니까? (0) | 2020.11.12 |