2

类似于这个问题。我正在使用 Rails 3.2,所以我知道我不需要 FasterCSV,我想做的是将所有数据导出到 CSV 文件。数据有一个父模型,它有七个 has_many 子节点,并且每个 has_many 子节点中可能有一个或多个记录。例如。

类 ParentModel < ActiveRecord::Base

has_many :child_1

has_many :child_2

has_many :child_3

然后

类 Child1 < ActiveRecord::Base

属于_to :parent_model

类 Child2 < ActiveRecord::Base

属于_to :parent_model

类 Child3 < ActiveRecord::Base

属于_to :parent_model

所以我有很多 ParentModel 记录,每个 ParentModel 记录可能有不同数量的 Child1、Child2 和 Child3 记录。如何动态找出 CSV 的第一行,然后填充 CSV,如果 ParentModel 恰好有一条 Child 记录,则插入 NULL?有没有一种有效的方法来做到这一点,或者它是否涉及很多循环?

例如,在整个数据库中,一个ParentModel最多有2条Child1记录,任何ParentModel最多只有1条Child2记录,有3条Child3记录。所以 CSV 的第一行是:

ParentModel.field1, ParentModel.field1, Child1.field1, Child1.field2, Child1(record#2).field1, Child1(record#2).field2, Child2.field1, Child2.field2,Child3.field1, Child3.field2, Child3(record#2).field1, Child3(record#2).field2, Child3(record#3).field1, Child3(record#3).field2

但随后另一个 Child1 被添加到 ParentModel,因此下次您进行导出时,它会计算出来,然后 CSV 的第一行将如下所示:

ParentModel.field1、ParentModel.field1、Child1.field1、Child1.field2、Child1(record#2).field1、Child1(record#2).field2、Child1(record#3).field1、Child1(record#3)。 field2, Child2.field1, Child2.field2,Child3.field1, Child3.field2, Child3(record#2).field1, Child3(record#2).field2, Child3(record#3).field1, Child3(record#3 ).field2

或者....在写完之后,我想知道我是否过于复杂化并且有一个平滑的“rails方式”来做到这一点?

谢谢!

4

1 回答 1

1

基本上,我必须弄清楚父模型拥有的最大子代数。然后,当它在 CSV 的每一行上导出一条记录时,它会用 a 填充子模型的列,-如果它没有与编号最多的记录一样多的子模型。(我知道,有点混乱,对吧?)

就我而言,我有可以有多个子记录的父模型。

class Parent < ActiveRecord::Base
  has_many :childs
...

class Child < ActiveRecord::Base
  belongs_to :parents
...

在 中ParentsController,我找到任何一个父级的最大数量childs,并获取 CSV 标题的列名。

class ParentsController < ApplicationController

def download    

@parents = Parent.all
# find maximum number of children any parent has. Make sure to convert to integer.
@max_children = Child.select('parent_id, COUNT(parent_id)').group(:parent_id).order('COUNT(parent_id) DESC').first.count.to_i

@parent_columns = Parent.column_names
@child_columns = Child.column_names

@streaming = true
@filename = "export.csv"

respond_to do |format|
  format.csv
end

然后在download.csv.csvbuilder我构建带有列名标题的 CSV 文件,以及父级可能从查询中获得的最大子级数的标题。

header = Array.new
@parent_columns.each do |column_name| 
  header << column_name.humanize 
end 

if @child_columns
    i = 0
    while i < @max_children do 
      @child_columns.each do |column_name| 
        header << "Child #{i+1} " + column_name.humanize 
      end
      i += 1
    end
end

csv << header.flatten

@parents.each do |parent|

  parent_record = Array.new

  parent_record << parent.attributes.values_at(*@parent_columns)

## NOTE: Here is the answer

if @child_columns
  if parent.childs.first.nil?
    i = 0
    while i < @max_children do 
        @child_columns.each do |column_name|
          parent_record << "-"
        end
      i += 1
    end
  elsif !parent.childs.first.nil?
    how_many_blanks = @max_children - parent.childs.length
    parent.childs.each do |child| 
      @child_columns.each do |child_column|
        parent_record << child.attributes.values_at(*child_column)
      end
    end
    i = 0
    while i < how_many_blanks do 
        @child_columns.each do |column_name|
          parent_record << "-"
        end
      i += 1
    end
  end
end

  csv << parent_record.flatten

end 

我希望这有帮助!

于 2014-11-18T18:11:41.637 回答