简体   繁体   中英

Display random records in Rails

I'm experimenting with Rails and wanted to display an array in an array, this works; code of index.html.erb beneath:

<div id="events">
  <% @events.each_with_index do |event, i| %>
    <%= link_to event_path(event) do %>
    <div class="card">
      <div class="image" style="background-image: url('<%= event.image.url %>')"></div>
      <div class="text">
        <h2><%= event.name %></h2>
        <div class="location"><%= event.location %></div>
        <date><strong><%= l event.date_start, :format => :day %> – <%= l event.date_end, :format => :day %> <%= l event.date_end, :format => :month %> </strong><%= l event.date_end, :format => :year %></date>
      </div>
    </div>
    <% end %>
    <%if i%1 == 1 %>
      <% @ads.find(:first) do |ad| %>
        <%= ad.name %>
      <% end %>
    <% end %>
    <%if (i+1)%4 == 0 %>
      <% @ads.find(:first) do |ad| %>
        <a href="<%= ad.url %>" target="_blank" class="ad">
          <div class="card">
            <%= ad.name %>
          </div>
        </a>
      <% end %>
    <% end %>
  <% end %>
</div>

And events_controller:

def index
  @ads = Ad.all.shuffle
end

Works pretty nice so far, after 4 @events items I get one @ads, random. However all @ads items are always the same random one.

How can I display random @ads items through the page without having the same one twice?

Try changing instances of @ads.find(:first) to @ads.pop - pop removes an item from the array and returns it - further calls to that array won't have the 'popped' item any more.

a = [ "a", "b", "c", "d" ]
a.pop     #=> "d"
a.pop(2)  #=> ["b", "c"]
a         #=> ["a"]

Instead of

def index
  @ads = Ad.all.shuffle
end

You could use

def index
  @ads = Ad.all.to_a.shuffle
end

while store all your Ad records in an array, shuffled

Then in your view, instead of

<% @ads.find(:first) do |ad| %>
  <%= ad.name %>
<% end %>

You could use

<% ad = @ads.pop %>
<%= ad.name %>

Which get you one Ad , and remove it from the array, so you won't get it a second time

Note we don't use a block in this case

Note also that when your array is empty, ad.name will raise NoMethodError , so you need to check on that too

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM