Reputation: 1086
I have an issue with associations and download via csv export.
My export works if data is present in the sales association, but if there is no data my export remains blank. Removing the i.sales.each do
part will export i.item_name
and i.item_number
fields fine.
So, if there is no data in my association my export remains blank. Is there a method to check if an association has information? I'm looking to include blank fields if no data is present.
I've tried i.try(:sales).each do |sale|
to no avail.
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
Upvotes: 2
Views: 729
Reputation: 1724
What @Sascha Mayr says is the normal way to go. Think about the data you want to present in that CSV. How would you call each one of those rows? Now it's a sale, no? But your source model is an item. If a new association were to be added, like "favs", how would you call then each row?
I want to illustrate that the nature of the data to present doesn't correctly fit in a CSV file (2 dimensions) if you start adding info from more associations. Something else should be done then, different CSV files, or grouping by some other concept.
Upvotes: 0
Reputation: 23671
You need to use left join to get all the records from the first table. This will give you NULL
values for the associated table, just as you want.
NOTE: Please change the references of Product
model/table with the appropriate one.
Rails 5 and above
left_joins(:sales).select('products.*, sales.sale_cost').each do |product|
csv << [
product.item_name,
product.item_number,
(product.sale_cost || 'N/A')
]
end
Rails 4 and below
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
This will result in something like:
pencil,12345,20
pencil,12345,10
eraser,11223,5
box,11333,N/A
Upvotes: 4
Reputation: 5609
Why not query your sales by association id ?
Assuming your i
is for an Item
model name, you can do something like:
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
or select just the records where sales are present:
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
Upvotes: 0
Reputation: 341
Try the following code
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
Upvotes: 0