Зацикливание нескольких массивов по годам

Я ищу несколько массивов, но имею проблемы с выравниванием их в таблице, основанной на году. В настоящий момент данные не совпадают с соответствующим годом, если данные существуют в любой год, он просто помещает данные в первую строку, а затем помещает '0' данные для остальных, т.е. не совпадая с годом.

Вид

<table>
<% @a.zip(@b, @c, @d) do |a, b, c, d| %>
 <tr>
  <td><%= a.year %></td>
  <% if a.blank? %>
    <td>0</td>
    <td>0</td>
  <% else %>
    <td><%= a.id %></td>
    <td><%= a.data %></td>
  <% end %>
  <% if b.blank? %>
    <td>0</td>
    <td>0</td>
  <% else %>
    <td><%= b.id %></td>
    <td><%= b.data %></td>
  <% end %>
  <% if c.blank? %>
    <td>0</td>
    <td>0</td>
  <% else %>
    <td><%= c.id %></td>
    <td><%= c.data %></td>
  <% end %>
  <% if d.blank? %>
    <td>0</td>
    <td>0</td>
  <% else %>
    <td><%= d.id %></td>
    <td><%= d.data %></td>
  <% end %>
 </tr>
</table>

контроллер

@a = Result.where(id: params[:id_select]).group('year').where('data > 0').select('AVG(data) AS data, year as year, COUNT(id) AS id').order('year ASC')

@b = Result.where(id: params[:id_select]).group('year').where('data > 0').select('AVG(data) AS data, year as year, COUNT(id) AS id').where('id = ?', '0').order('year ASC')

@c = Result.where(id: params[:id_select]).group('year').where('data > 0').select('AVG(data) AS data, year as year, COUNT(id) AS id').where('id = ?', '1').order('year ASC')

@d = Result.where(id: params[:id_select]).group('year').where('data > 0').select('AVG(data) AS data, year as year, COUNT(id) AS id').where('id = ?', '2').order('year ASC')

Ответ 1

Я думаю, вы можете попробовать это. в этом вам не нужно проверять пустые значения. я надеюсь, что @a содержит все ваши доступные годы, в противном случае вам нужно объединить все годы цикла через годы.

<table>
<% @a.each do |a| %>
 <tr>
  <td><%= a.year %></td>
    <td><%= (a.id || 0 rescue 0) %></td>
    <td><%= (a.data || 0 rescue 0) %></td>
    <td><%= (@b.select{|h| h if h["year"] == a.year }.first.id || 0 rescue 0) %></td>
    <td><%= (@b.select{|h| h if h["year"] == a.year }.first.data || 0 rescue 0 ) %></td>
    <td><%= (@c.select{|h| h if h["year"] == a.year }.first.id || 0 rescue 0) %></td>
    <td><%= (@c.select{|h| h if h["year"] == a.year }.first.data || 0 rescue 0) %></td>
    <td><%= (@d.select{|h| h if h["year"] == a.year }.first.id || 0 rescue 0) %></td>
    <td><%= (@d.select{|h| h if h["year"] == a.year }.first.data || 0 rescue 0) %></td>
 </tr>
<% end %>
</table>

Если ваш @a не содержит все годы, просто попробуйте объединить его с помощью

years = ((@a.collect{|h| h["year"]}) + (@b.collect{|h| h["year"]}) + (@c.collect{|h| h["year"]}) + (@d.collect{|h| h["year"]})).uniq

тогда вы можете просто прокручивать массив years как:

<% years.each do |year| %>
     <tr>
      <td><%= year %></td>
        <td><%= (@a.select{|h| h if h["year"] == year }.first.id || 0 rescue 0) %></td>
        <td><%= (@a.select{|h| h if h["year"] ==  year }.first.data || 0 rescue 0 ) %></td>
        <td><%= (@b.select{|h| h if h["year"] == year }.first.id || 0 rescue 0) %></td>
        <td><%= (@b.select{|h| h if h["year"] ==  year }.first.data || 0 rescue 0 ) %></td>
        <td><%= (@c.select{|h| h if h["year"] == year }.first.id || 0 rescue 0) %></td>
        <td><%= (@c.select{|h| h if h["year"] == year }.first.data || 0 rescue 0) %></td>
        <td><%= (@d.select{|h| h if h["year"] == year }.first.id || 0 rescue 0) %></td>
        <td><%= (@d.select{|h| h if h["year"] == year }.first.data || 0 rescue 0) %></td>
     </tr>
    <% end %>
    </table>

Ответ 2

Вероятно, вы имеете в виду это:

<%
  A = @a.group_by{|a| a.year}
  B = @b.group_by{|b| b.year}
  C = @c.group_by{|c| c.year}
  D = @d.group_by{|d| d.year}
%>

<table>
  <% A.each do |year, a| %>
    <% b = B[year] %>
    <% c = C[year] %>
    <% d = D[year] %>
    <tr>
      <td><%= year %></td>
      <% if a.blank? %>
        <td>0</td>
        <td>0</td>
      <% else %>
        <%= a.id %>
        <%= a.data %>
      <% end %>
      <% if b.blank? %>
        <td>0</td>
        <td>0</td>
      <% else %>
        <td><%= b.id %></td>
        <td><%= b.data %></td>
      <% end %>
      <% if c.blank? %>
        <td>0</td>
        <td>0</td>
      <% else %>
        <td><%= c.id %></td>
        <td><%= c.data %></td>
      <% end %>
      <% if d.blank? %>
        <td>0</td>
        <td>0</td>
      <% else %>
        <td><%= d.id %></td>
        <td><%= d.data %></td>
      <% end %>
    </tr>
  <% end %>
</table>

Я предполагаю, что здесь @a содержит все годы, которые могут содержать другие массивы (на основе запроса). Если это не так, вам сначала нужно создать полный массив лет:

<% years = (A.keys + B.keys + C.keys + D.keys).uniq %>
<table>
  <% years.each do |year| %>
    <% a = A[year] %>
    <!-- the rest is the same, as above -->
  <% end %>
</table>

Ответ 3

В контроллере:

@results_by_year = Result.where(your_conditions).group_by(&:year)
# this retrieves all the Result records wanted, without taking care of the record `year`

Структура хэша будет выглядеть следующим образом:

# { 2010: [<Result id:1>, <Result id:3>], 
#   2012: [<Result id:2>], 
#   2014: [<Result id:7>, <Result id:9>] }

В представлении:

@results_by_year.each do |year, results|
  = year
  - results.each do |result|
    = result.id
    = result.data
end