使用 Association 导入 CSV
Import CSV with Association
我有 2 个模型 Order has_many line_items
和 line_item belongs_to order
。订单已创建,文件导入表单在订单展示表单中。我正在使用 roo gem 进行 CSV 导入,但如果有其他解决方案,我不必这样做。电子表格中的每一行都是新的 line_item,但我需要为每一行保存 order_id。我对所有解决方案持开放态度。
orders/show.html.erb
<%= form_tag import_line_items_path, multipart: true do %>
<%= file_field_tag :file %>
<%= submit_tag "Import" %>
<% end %>
line_items_controller.rb
def import
LineItem.import(params[:file])
redirect_to root_path, notice: "Products imported."
end
def edit
end
def create
@line_item = LineItem.new(line_item_params, :order_id => :order_id)
respond_to do |format|
if @line_item.save
format.html { redirect_to @line_item, notice: 'Line item was successfully created.' }
format.json { render :show, status: :created, location: @line_item }
else
format.html { render :new }
format.json { render json: @line_item.errors, status: :unprocessable_entity }
end
end
end
line_item.rb
class LineItem < ActiveRecord::Base
require 'csv'
belongs_to :order, inverse_of: :line_items
def self.import(file)
spreadsheet = Roo::Spreadsheet.open(file.path)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
line_item = find_by(id: row["id"]) || new
line_item.attributes = row.to_hash
line_item.order_id = @order
puts @order
line_item.save!
end
end
end
这是我在使用此代码时遇到的错误...
Validation failed: Order must exist
您必须将 order
传递给 import
操作和 self.import
方法。例如:
orders/show.html.erb
<%= form_tag import_line_items_path, multipart: true do %>
# Send order_id via hidden_field_tag
<%= hidden_field_tag :order_id, params[:id] %>
<%= file_field_tag :file %>
<%= submit_tag "Import" %>
<% end %>
line_items_controller.rb
def import
order = Order.find(params[:order_id])
LineItem.import(params[:file], order)
redirect_to root_path, notice: "Products imported."
end
line_item.rb
def self.import(file, order)
spreadsheet = Roo::Spreadsheet.open(file.path)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
line_item = find_by(id: row["id"]) || new
line_item.attributes = row.to_hash
line_item.order_id = order.id
puts order
line_item.save!
end
end
我有 2 个模型 Order has_many line_items
和 line_item belongs_to order
。订单已创建,文件导入表单在订单展示表单中。我正在使用 roo gem 进行 CSV 导入,但如果有其他解决方案,我不必这样做。电子表格中的每一行都是新的 line_item,但我需要为每一行保存 order_id。我对所有解决方案持开放态度。
orders/show.html.erb
<%= form_tag import_line_items_path, multipart: true do %>
<%= file_field_tag :file %>
<%= submit_tag "Import" %>
<% end %>
line_items_controller.rb
def import
LineItem.import(params[:file])
redirect_to root_path, notice: "Products imported."
end
def edit
end
def create
@line_item = LineItem.new(line_item_params, :order_id => :order_id)
respond_to do |format|
if @line_item.save
format.html { redirect_to @line_item, notice: 'Line item was successfully created.' }
format.json { render :show, status: :created, location: @line_item }
else
format.html { render :new }
format.json { render json: @line_item.errors, status: :unprocessable_entity }
end
end
end
line_item.rb
class LineItem < ActiveRecord::Base
require 'csv'
belongs_to :order, inverse_of: :line_items
def self.import(file)
spreadsheet = Roo::Spreadsheet.open(file.path)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
line_item = find_by(id: row["id"]) || new
line_item.attributes = row.to_hash
line_item.order_id = @order
puts @order
line_item.save!
end
end
end
这是我在使用此代码时遇到的错误...
Validation failed: Order must exist
您必须将 order
传递给 import
操作和 self.import
方法。例如:
orders/show.html.erb
<%= form_tag import_line_items_path, multipart: true do %>
# Send order_id via hidden_field_tag
<%= hidden_field_tag :order_id, params[:id] %>
<%= file_field_tag :file %>
<%= submit_tag "Import" %>
<% end %>
line_items_controller.rb
def import
order = Order.find(params[:order_id])
LineItem.import(params[:file], order)
redirect_to root_path, notice: "Products imported."
end
line_item.rb
def self.import(file, order)
spreadsheet = Roo::Spreadsheet.open(file.path)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
line_item = find_by(id: row["id"]) || new
line_item.attributes = row.to_hash
line_item.order_id = order.id
puts order
line_item.save!
end
end