Rails通过关联导出到CSV

时间:2019-06-06 00:32:31

标签: ruby-on-rails ruby-on-rails-5

我对关联有疑问,可以通过csv导出进行下载。

如果销售关联中存在数据,则我的导出有效,但是如果没有数据,我的导出将保持空白。删除i.sales.each do部分将可以导出i.item_namei.item_number字段。

因此,如果我的关联中没有数据,我的导出将保持空白。有没有检查关联信息的方法?如果没有数据,我希望包括空白字段。

我尝试i.try(:sales).each do |sale|无济于事。

CSV.generate(headers: true) do |csv|
  csv << attributes
  all.each do |i|
    i.sales.each do |sale|
      csv << [
          i.item_name,
          i.item_number,
          sale.try(:sale_cost)
      ]
     end
   end
 end

4 个答案:

答案 0 :(得分:4)

您需要使用左连接来从第一个表中获取所有记录。可以根据需要为您的关联表提供NULL个值。

注意:请更改Product模型/表的引用以及相应的引用。

排名5及以上

left_joins(:sales).select('products.*, sales.sale_cost').each do |product|
  csv << [
    product.item_name,
    product.item_number,
    (product.sale_cost || 'N/A')
  ]
end

排名4及以下

Product.joins("left join sales on products.id = sales.product_id")
       .select('products.*, sales.sale_cost')
       .each do |product|

  csv << [
    product.item_name,
    product.item_number,
    (product.sale_cost || 'N/A')
  ]
end

这将导致类似以下内容:

pencil,12345,20
pencil,12345,10 
eraser,11223,5
box,11333,N/A

答案 1 :(得分:0)

尝试以下代码

CSV.generate(headers: true) do |csv|
  csv << attributes
  all.each do |i|
    if i.sales.present?
     i.sales.each do |sale|
       csv << [
           i.item_name,
           i.item_number,
           sale.try(:sale_cost)
       ]
      end
    else
     csv << [
       i.item_name,
       i.item_number
     ]
    end
   end
 end

答案 2 :(得分:0)

为什么不按关联ID查询您的销售?
假设您的iItem模型名称,则可以执行以下操作:

all.each do |i|
  Sale.where(item_id: i.id).each do |sale|
    csv << [
      i.item_name,
      i.item_number,
      sale.try(:sale_cost)
    ]
  end
end

或仅选择存在销售记录:

joins(:sales).group('items.id').each do |i|
  i.sales.each do |sale|
    csv << [
      i.item_name,
      i.item_number,
      sale.try(:sale_cost)
    ]
  end
end

答案 3 :(得分:0)

@Sascha Mayr所说的是正常的做法。考虑一下要在该CSV中显示的数据。您将如何称呼这些行中的每一行?现在是销售,不是吗?但是您的源模型是一个项目。如果要添加一个新的关联,例如“收藏夹”,那么您将如何调用每一行?

我想说明的是,如果您开始从更多关联中添加信息,则要显示的数据的性质就不能正确地适合CSV文件(2维)。然后,应该执行其他操作,使用不同的CSV文件或按其他概念进行分组。