csv出力
- view
<%= link_to "CSV", products_path(format: :csv) %>
- controller
def index
respond_to do |format|
format.html do
@search = Product.ransack(params[:q])
@products = @search.result
end
format.csv do
@products = Product.all
data= CSV.generate do |csv|
column_names = %w[id title product_price_id]
csv << column_names
@products.each do |product|
row = [product.id, product.title, product.product_price_id]
csv << row
end
end
send_data(data, filename: 'produsts.csv')
end
end
end
csv アップロード
- gem
gem 'roo'
- routes
resources :products do
collection do
post :import
end
end
- controller
def import
Product.import(params[:csv_file])
redirect_to root_path
end
- model
class Product < ApplicationRecord
belongs_to :product_price
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
product = Product.new
product.attributes = row.to_hash.slice(*updatable_attributes)
product.save
end
end
def self.updatable_attributes
["title","product_price_id"]
end
- spec
require 'rails_helper'
RSpec.describe ProductsController, type: :controller do
describe '#index' do
before do
price = ProductPrice.create(price: 2000)
Product.create(title: "Product1", product_price_id: price.id)
end
it 'csv出力する' do
get :index, format: :csv
expect(response.body).to include "Product1"
end
context 'アップロード' do
before do
ProductPrice.create(id:1, price: 2000)
ProductPrice.create(id:2, price: 2000)
end
let(:csv_file) {'test.csv'}
subject do
post :import, params: {
csv_file: fixture_file_upload(csv_file, 'text/csv')
}
end
it 'aa' do
expect{subject}.to change(Product,:count).by(2)
end
end
end
end