从Ruby on Rails中的不同类导入具有不同属性的Excel文件

时间:2017-03-24 07:57:44

标签: ruby-on-rails ruby

我想从不同的类导入具有不同属性的excel。我有两个模型Student和Guardian。问题是当我导入File作为Student时它必须插入Student表中,当我导入Guardian文件时它应该插入Guardian表中。但是现在我没有得到控制器将如何获得所选文件是学生或卫报的文件。现在当我写BeanShell Sampler时,文件被插入到监护人表中,当我Guardian.import(params[:file])时,文件被插入学生表中。

控制器

Student.import(params[:file])

模型

def import
    Guardian.import(params[:file])
    redirect_to import_reports_path, notice: "Students imported."
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]
    row = clean_for row, COLUMNS_TO_STRING
    record = Student.find_by(:batch_id =>        row["batch_id"],:class_roll_no => row["class_roll_no"],:phone1 =>   row["phone1"],:phone2 => row["phone2"]) || new
    guardian = Guardian.find_by(:student_id => row["student_id"]) || new
    record.attributes = row.to_hash.slice(*row.to_hash.keys)
    guardian.attributes = row.to_hash.slice(*row.to_hash.keys)
    record.save!
    guardian.save!
  end
 end

def self.clean_for row_as_hash, string_columns_array
  row_as_hash.each do |key, value|
    if string_columns_array.include?key
      row_as_hash[key] = value.to_i.to_s
    end
  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::Excel.new(file.path)
  when ".xlsx" then Roo::Excelx.new(file.path)
  else raise "Unknown file type: #{file.original_filename}"
end
end

2 个答案:

答案 0 :(得分:0)

通常有两种方法,具体取决于您当前的结构。如果您对每种类型都有不同的登录,那么您可以通过检查current_user.role之类的内容在控制器中执行此操作。

def importer
  if current_user.guardian?
    Guardian
  else
    Student
  end
end

如果您有不同表单的不同页面,您可以随时在role

中发送的表单中添加隐藏字段
def importer
  params[:role] == :guardian ? Guardian : Student
end

上述任何一种都可以添加到控制器中。最后,您只需要使用该方法。

importer.import(params[:file])

答案 1 :(得分:0)

我想从不同的类导入具有不同属性的excel。 在这里,我找到了解决这个问题的好方法。 因为我想保留学生和监护人excel数据的报告。 我的错误是我没有查看报告名称,即学生,卫报控制器出错了

  

以下是我的问题的解决方案:

<强> report_controller.rb

class ReportsController < ApplicationController
before_action :load_report, only: [:import, :import_form], unless: -> { params[:id].nil? }
def import_form
end

def import
 importer = @report.name == 'Guardian' ? Guardian : Student
 importer.import(params[:file])
 redirect_to import_form_report_path, notice: "#{importer}s imported."
end

private 

def load_report
 @report = Report.find_by_id(params[:id])
end
end
  

更改路线

<强>的routes.rb

 member do 
      get :import_form
      post :import 
    end

查看

<%= form_tag import_report_path(@report), method: :post, multipart: true do %>

链接

<td><%= link_to 'IMPORT' , import_form_report_path(report)%></td>
  

student.rb和guardian.rb中的代码将保持与上述相同。