我需要一个关于如何导入具有不同属性的CSV文件的示例。到目前为止,当我运行我的代码时,我收到一条错误消息,指出未知属性' email'为学生。电子邮件属性可以来自Parent。除了仅为学生导入属性和仅导入父级。如何在学生属性中导入父属性?
我的程序工作在我的学生计划中导出带有父属性的CSV时发现。
任何帮助将不胜感激。
学生模特课:
class Student < ActiveRecord::Base
belongs_to :parent
delegate :email,:name,:phone_number,to: :parent, allow_nil: true
def self.to_csv
attributes = %w{parent_id email phone_number first_name last_name age workshop interest registration_date email }
CSV.generate(headers: true) do |csv|
csv << attributes
all.each do |script|
csv << attributes.map{ |attr| script.send(attr) }
end
end
end
def self.import(file)
spreadsheet = open_spreadsheet(file)
header=spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header,spreadsheet.row(i)].transpose]
#CSV.foreach(file.path, headers: true) do |row|
student = find_by_id(row["id"])|| new
student.attributes = row.to_hash.slice(*row.to_hash.keys)
student.save!
end
end
def self.open_spreadsheet(file)
case File.extname(file.original_filename)
when ".csv" then Roo::CSV.new(file.path)
when ".xls" then Roo::CSV.new(file.path)
when ".xlsx" then Roo::CSV.new(file.path)
else raise "Unknown file type: #{file.original_filename}"
end
end
end
学生管理员:
def import
Student.import(params[:file])
redirect_to root_url, notice: "student imported."
end
end
查看文件夹:
<h2>Import Students</h2>
<%= form_tag import_students_path, multipart: true do %>
<%= file_field_tag :file %>
<%= submit_tag "Import" %>
<% end %>
答案 0 :(得分:0)
我想建议你的第一件事就是保持你的模型代码很薄。最佳做法是让您的模型仅对数据负责,否则为紫罗兰SRP。
class ImportStudentsService
SUPPORTED_TYPES = ['.csv', '.xls', '.xlsx'].freeze
STUDENT_ATTRIBUTES = %w(
parent_id first_name last_name
age workshop interest registration_date
).freeze
PARENT_ATTRIBUTES = %w(email phone_number email).freeze
def initialize(file)
@file = file
end
def call
import
end
private
def import
spreadsheet.each do |row|
student = Student.find_or_initialize_by(id: row['id'])
parent = student.parent || student.build_parent
student.attributes = row.slice(*STUDENT_ATTRIBUTES)
parent.attributes = row.slice(*PARENT_ATTRIBUTES)
student.save!
parent.save!
end
end
def spreadsheet
unless SUPPORTED_TYPES.include?(File.extname(@file.original_filename))
raise "Unknown file type: #{@file.original_filename}"
end
Roo::CSV.new(@file.path)
end
end
在控制器中
def import
ImportStudentsService.new(params[:file]).call
redirect_to root_url, notice: "student imported."
end
这不是100%正常工作的代码,但这里提出了主要想法。