Rails: An elegant way to display a message when there are no elements in database

后端 未结 10 1028
花落未央
花落未央 2020-12-04 09:51

I realized that I\'m writing a lot of code similar to this one:

<% unless @messages.blank? %>
  <% @messages.each do |message|  %>
    <%# cod         


        
相关标签:
10条回答
  • 2020-12-04 10:05

    You can create some custom helper. The following one is just an example.

    # 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 %>
    
    0 讨论(0)
  • 2020-12-04 10:14

    I'm surprised my favorite answer isn't up here. There is an answer thats close, but I don't like bare text and using content_for is klunky. Try this one on for size:

      <%= render(@user.recipes) || content_tag("p") do %>
        This user hasn't added any recipes yet!
      <% end %>
    
    0 讨论(0)
  • 2020-12-04 10:15

    You could also write something like this:

    <% if @messages.each do |message| %>
      <%# code or partial to display the message %>
    <% end.empty? %>
      You have no messages.
    <% end %>
    
    0 讨论(0)
  • 2020-12-04 10:19

    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.

    0 讨论(0)
  • 2020-12-04 10:20

    One way is to do something like:

    <%= render(:partial => @messages) || render('no_messages') %>
    

    Edit:

    If I remember correctly this was made possible by this commit:

    http://github.com/rails/rails/commit/a8ece12fe2ac7838407954453e0d31af6186a5db

    0 讨论(0)
  • 2020-12-04 10:20

    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.

    0 讨论(0)
提交回复
热议问题