Ruby / Rails - наиболее эффективный способ разделения массива на две группы на основе параметра и отображения обоих - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть модель «Монета», которая имеет логический параметр «принято».Я хочу сначала отобразить все объекты, которые приняты, после чего следует перерыв, а затем отобразить те, которые не приняты (поэтому я не хочу просто сортировать их и отображать их все).Каков наиболее эффективный способ сделать это?Ниже показано, как это у меня сейчас, но я чувствую, что должен быть лучший способ.

<% @accepted = @coin_events.select { |event| event.accepted == true } %>
<% @pending = @coin_events.select { |event| event.accepted == false } %>

<% @accepted.each do |event| %>
  <ul><b>Event: </b><%= event.content %></ul>
  <ul><b>Category: </b><%= event.coin.currency_name %></ul>
  <ul><b>Link: </b><%= event.link %></ul>
  <ul><b>Date: </b><%= event.date.strftime('%a %b %d %Y') if defined?(event.date) %></ul>
  <ul><b>Location: </b><%= event.city %>, <%= event.state %>, <%= event.country %></ul>
  <ul><b>Description: </b><%= event.description %></ul>
  <ul><b>Submitted by: </b><%= event.user.username %></ul>
  <% if can? :edit, Coin %>
    <ul><b>Accepted: </b><%= event.accepted %></ul>
  <% end %>

  <div class="btn-group" id="event-buttons">    
    <% if can? :update, event and @coin.moderator == current_user or current_user.admin? %>
      <%= link_to "View Event", coin_event_path(event.coin_id, event.id), class: "btn btn-default" %>       
      <%= link_to "Edit", edit_coin_event_path(event.coin_id, event.id), class: "btn btn-default" %>
    <% end %>
    <% if can? :destroy, event and current_user.admin? %>
      <%= link_to "Delete", coin_event_path(event.coin_id, event.id), method: :delete, data: { confirm: "Do you want to delete this submission?" }, class: "btn btn-default" %>
    <% end %>
  </div>
<% end %>

<!-- OTHER STUFF HERE --> 

<% @pending.each do |event| %>

  <ul><b>Event: </b><%= event.content %></ul>
  <ul><b>Category: </b><%= event.coin.currency_name %></ul>
  <ul><b>Link: </b><%= event.link %></ul>
  <ul><b>Date: </b><%= event.date.strftime('%a %b %d %Y') if defined?(event.date) %></ul>
  <ul><b>Location: </b><%= event.city %>, <%= event.state %>, <%= event.country %></ul>
  <ul><b>Description: </b><%= event.description %></ul>
  <ul><b>Submitted by: </b><%= event.user.username %></ul>
  <% if can? :edit, Coin %>
    <ul><b>Accepted: </b><%= event.accepted %></ul>
  <% end %>

  <div class="btn-group" id="event-buttons">    
    <% if can? :update, event and @coin.moderator == current_user or current_user.admin? %>
      <%= link_to "View Event", coin_event_path(event.coin_id, event.id), class: "btn btn-default" %>       
      <%= link_to "Edit", edit_coin_event_path(event.coin_id, event.id), class: "btn btn-default" %>
    <% end %>
    <% if can? :destroy, event and current_user.admin? %>
      <%= link_to "Delete", coin_event_path(event.coin_id, event.id), method: :delete, data: { confirm: "Do you want to delete this submission?" }, class: "btn btn-default" %>
    <% end %>
  </div>
<% end %>

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

В Ruby есть метод partition, который делает именно то, что вам нужно.

partition { |obj| block } → [ true_array, false_array ]

Возвращает два массива, первый из которых содержит элементы enum, для которых блок оценивается как true, второй - остальные.

В вашем примере partition можно использовать так:

@accepted, @pending = @coin_events.partition(&:accepted)

Кроме того, похоже, что оба блока HTML идентичны.Тогда кажется хорошей возможностью создать частичку из одного из этих блоков:

# the new partial `_event.html.erb`
<ul><b>Event: </b><%= event.content %></ul>
<ul><b>Category: </b><%= event.coin.currency_name %></ul>
<ul><b>Link: </b><%= event.link %></ul>
... ...
    <%= link_to "Delete", coin_event_path(event.coin_id, event.id), method: :delete, data: { confirm: "Do you want to delete this submission?" }, class: "btn btn-default" %>
  <% end %>
</div>

И повторно использовать эту частичку для рендеринга обеих коллекций:

<%= render @accepted %>
<!-- OTHER STUFF HERE --> 
<%= render @pending %>

Советую прочитать о Частицы в направляющих рельсов .

0 голосов
/ 19 сентября 2018

Все, что html кажется идентичным для каждого типа event.

Итак, сделайте что-то вроде:

<% @accepted = @coin_events.select { |event| event.accepted == true } %>
<% @pending = @coin_events.select { |event| event.accepted == false } %>

<% @accepted.each do |event| %>
  render partial: 'event', locals: {event: event}
<% end %>

<!-- OTHER STUFF HERE --> 

<% @pending.each do |event| %>
  render partial: 'event', locals: {event: event}
<% end %>

И затем поместите весь свой html в партиал _event.(Примечание: не проверено, вам может понадобиться возиться с этим.)

Также, пожалуйста, не ставьте:

<% @accepted = @coin_events.select { |event| event.accepted == true } %>
<% @pending = @coin_events.select { |event| event.accepted == false } %>

на ваш взгляд.Это должно быть в вашем контроллере.

И в вашем контроллере кажется, что вы должны быть в состоянии сделать:

@accepted = @coin_events.where(accepted: true)
@pending = @coin_events.where(accepted: false)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...