使用 Rails 对数据进行分组和分页

发布于 2024-10-15 18:11:12 字数 1694 浏览 3 评论 0原文

我有 csv 导入表模型:

class ImportTable < ActiveRecord::Base
   has_many :import_cells, :dependent => :destroy
end

class ImportCell < ActiveRecord::Base
    belongs_to :import_table
end

控制器是(为简洁起见进行编辑):

def show
   @import_table = ImportTable.find(params[:id])

   @import_cells = @import_table.import_cells
   @row_index_max = @import_cells.map { |cell| cell.row_index }.max
   @column_index_max = @import_cells.map { |cell| cell.column_index }.max
end

import_cells 有 row_indexcolumn_index,我按视图中的列对它们进行分组。

<table border="1" cellspacing="1" cellpadding="1">
<tr>
  <% 0.upto(@column_index_max) do |column_index| %>
    <th>
      <%= f.select(column_index, []) %>
    </th>
  <% end %>
</tr>
<% 0.upto(@row_index_max) do |row_index| %>
<% row = @import_cells.select { |cell| cell.row_index == row_index } %>
<tr>
  <% 0.upto(@column_index_max) do |column_index| %>
    <td>
      <%= row.select { |cell| cell.column_index == column_index }[0].contents %>
    </td>
  <% end %>
</tr>
<% end %>
</table>

我从另一个网站抄袭了这个,对我来说似乎有点笨拙。简单地添加:

@import_cells = @import_table.import_cells.paginate(:all, :order => "row_index ASC", :per_page => @column_index_max * 16, :page => params[:page])

不太有效,因为需要处理 will_paginate 创建的 nil 对象。在我看来,这个观点的逻辑太多了。这里采取什么好方法?我正在考虑添加一个 row 方法来对 ImportTable 模型本身中的列进行分组,但它必须灵活,具体取决于特定表中的列数。然后可以对行进行分页。

任何关于“rails way”方向的想法、建议和推动都值得赞赏!

I have csv import table model:

class ImportTable < ActiveRecord::Base
   has_many :import_cells, :dependent => :destroy
end

class ImportCell < ActiveRecord::Base
    belongs_to :import_table
end

The controller is (edited for brevity):

def show
   @import_table = ImportTable.find(params[:id])

   @import_cells = @import_table.import_cells
   @row_index_max = @import_cells.map { |cell| cell.row_index }.max
   @column_index_max = @import_cells.map { |cell| cell.column_index }.max
end

The import_cells have a row_index and column_index, I group them by columns in the view.

<table border="1" cellspacing="1" cellpadding="1">
<tr>
  <% 0.upto(@column_index_max) do |column_index| %>
    <th>
      <%= f.select(column_index, []) %>
    </th>
  <% end %>
</tr>
<% 0.upto(@row_index_max) do |row_index| %>
<% row = @import_cells.select { |cell| cell.row_index == row_index } %>
<tr>
  <% 0.upto(@column_index_max) do |column_index| %>
    <td>
      <%= row.select { |cell| cell.column_index == column_index }[0].contents %>
    </td>
  <% end %>
</tr>
<% end %>
</table>

I cribbed this from another website and it seems sort of janky to me. Simply adding:

@import_cells = @import_table.import_cells.paginate(:all, :order => "row_index ASC", :per_page => @column_index_max * 16, :page => params[:page])

Doesn't quite work as there will be nil objects created by will_paginate that have to be dealt with. It seems to me there is too much logic in the view. What's a good approach to take here? I'm thinking of adding a row method to group the columns in the ImportTable model itself but it would have to be flexible depending on how many columns are in a particular table. Then the rows could be paginated.

Any thoughts, suggestions, and nudges in the "rails way" direction appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怎言笑 2024-10-22 18:11:12

我们在我正在开发的网站上有一个与此类似的设置,我按如下方式处理它:

在控制器中构建一个“表”(实际上是一个数组的数组):

@table = []
max_col = 0
@table_cells.each do |cel|
    @table[cel.row] ||= []
    @table[cel.row][cel.col] = cel
    max_col = [max_col, cel.col].max
end

#This bit fleshes out your rows with nils to ensure you have a rectangular table:
# (edited to handle empty rows properly)
@table.each_with_index do |row, i|
    @table[i] = [] unless row
    @table[i][max_col] ||= nil
end

在视图中,您所要做的就是是循环遍历表格并显示单元格:

<table>
<% @table.each do |row| -%>
    <tr>
<% row.each do |cel| -%>
        <td><%=h cel.whatever %></td>
<% end -%>
    </tr>
<% end -%>
</table>

此方法的缺点是您必须在渲染页面之前在内存中构建整个表格(如果您对列进行了正确排序,您可能可以一次一行地进行)。优点是它很好地遵循 MVC(以及“Rails Way”),并且一旦您拥有构建它的函数,@table 就会非常有用 - 一旦您拥有它,您就可以输出只需调整视图即可实现任何您想要的格式。我们将其用于 HTML 和 CSV,并计划在有人有时间学习该格式后立即添加 XLS。

We have a setup similar to this in the site I'm working on, and I dealt with it as follows:

Build a "table" (actually an array of arrays) in the controller:

@table = []
max_col = 0
@table_cells.each do |cel|
    @table[cel.row] ||= []
    @table[cel.row][cel.col] = cel
    max_col = [max_col, cel.col].max
end

#This bit fleshes out your rows with nils to ensure you have a rectangular table:
# (edited to handle empty rows properly)
@table.each_with_index do |row, i|
    @table[i] = [] unless row
    @table[i][max_col] ||= nil
end

And in the view, all you have to do is loop through the table and show the cels:

<table>
<% @table.each do |row| -%>
    <tr>
<% row.each do |cel| -%>
        <td><%=h cel.whatever %></td>
<% end -%>
    </tr>
<% end -%>
</table>

The downside of this method is that you have to build the whole table in memory before rendering the page (you could probably do it a row at a time if you sorted your columns properly). The upsides are that it sticks to MVC (and thus the "Rails Way") pretty nicely, and @table is widely useful once you have a function to build it - once you have it, you can output just about any format you want just by tweaking the view. We use it for HTML and CSV, and plan to add XLS as soon as someone has time to learn the format.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文