【问题标题】:import CSV file with different attributes from a different class从不同的类导入具有不同属性的 CSV 文件
【发布时间】:2016-08-10 13:53:33
【问题描述】:

我需要一个关于如何导入具有不同属性的 CSV 文件的示例。到目前为止,当我运行我的代码时,我收到一条错误消息,指出 Student 的未知属性“电子邮件”。电子邮件属性可以来自父级。除了只为学生和家长导入属性。如何在学生属性中导入父母的属性?

当我在学生程序中导出带有父母属性的 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 %>

【问题讨论】:

  • 请提供您的代码和错误。
  • @Uzbekjon 我用代码编辑我的帖子。谢谢
  • 能否也添加错误堆栈跟踪?
  • @Uzbekjon 错误消息突出显示:student.attributes = row.to_hash.slice(*row.to_hash.keys) app/models/student.rb:69:in block in import' app/models/student.rb:65:in import' app /controllers/students_controller.rb:15:in `import'
  • @Uzbekjon 我是否发布了正确的错误堆栈跟踪

标签: ruby-on-rails ruby csv export-to-csv


【解决方案1】:

我想建议您的第一件事是“保持模型代码精简”。最好的做法是让你的模型只对数据负责,否则它会变成紫罗兰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% 有效的代码,但主要思想在这里提出。

【讨论】:

  • 我同意保持 mu 模型类代码精简,但是是否可以帮助我处理我的程序代码。你能给我举个例子,说明如何在学生属性中导入父母的属性吗?
  • 我定义了两个保持学生和父母属性的常量,映射发生在这里。 Thinks 示例已经将一些数据导入到父模型中。
  • 当我使用您的 def 导入方法时,我收到一条错误消息,没有将 String 隐式转换为 Integer
猜你喜欢
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
  • 1970-01-01
  • 2019-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-29
相关资源
最近更新 更多