Ruby创建Tempfile以保存CSV行并将其分配给数据库

时间:2017-08-23 23:20:11

标签: mysql ruby-on-rails ruby excel csv

我这里有一个非常复杂的问题。

我使用CSV库导出两个电子表格,两张表之间有一对多关联

问题是我需要根据特定行中的值保存Result记录的外键,然后保存下一行的其余数据 所以这里有一个例子

 1023115111      | SUMMARY   |  1.5 | 2 | 2.5

 8/16/2017 23:00 |     1.3   |  1.5 | 2 | 2.5

 1023201         | SUMMARY   |  1.9 | 2 | 2.1

 8/16/2017 7:10  |    1.76   |  1.9 | 2 | 2.1

 8/16/2017 15:00 |    1.76   |  1.9 | 2 | 2.1

以下是问题

我需要在汇总行存在的第一个单元格中进行比较,然后比较它找到它所在的机器" mid"等于这个值

然后跳过整行并保存"结果"到新记录,其中machine_id等于此值

我会尽力使其更清晰

@mid = row(0)     

@machine = Machine.where(mid: @mid)     

然后

Result.create(line: line, min: min, exps: real, max: max, 
 ideal: mean, time: time, machine_id: @machine.id  )       

这是我的结果模型

require 'csv'    
require 'tempfile'    
require 'fileutils'    
class Result < ActiveRecord::Base
belongs_to :machine
def self.assign_row(row)     
   line, b, time, real, min, mean, max = row
   Result.create(line: line, min: min, exps: real, max: max, ideal: mean, time: time  )    
      end    

def self.import(file)    
   CSV.foreach(file.path, encoding: 'iso-8859-1:utf-8', skip_blanks: true) do |row|    
  next if row[3] =~ /SUMMARY/       
  next if row.all?(&:nil?)       
  result = Result.assign_row(row)       
    end     
   end     
  end     

这是我的机器模型

require 'csv'    
class Machine < ActiveRecord::Base    
validates_uniqueness_of  :name    
has_many :results    
def self.assign_row(row)
 a, b, c = row
 if row[2].nil?
  puts 'na'
 else

 @mid = c[0..2]
 @name = c[5..-1]
end
machine = Machine.find_by(name: c)
Machine.create(name: @name, mid: @mid) if machine.blank?
end

def self.import(file)    
     CSV.foreach(file.path, encoding: 'iso-8859-1:utf-8', skip_blanks: true) do |row|    
 machine = Machine.assign_row(row)    
   end    
 end    
end    

结果迁移

class CreateResults < ActiveRecord::Migration     
def change      
create_table :results do |t|      
  t.string :min      
  t.string :max      
  t.string :time     
  t.string :exps     
  t.references :machine, index: true, foreign_key: true     
  t.string :line     
  t.string :ideal     

  t.timestamps null: false     
     end     
   end     
 end      

机器迁移

 class CreateMachines < ActiveRecord::Migration     
 def change     
 create_table :machines do |t|     
  t.string :name     
  t.string :mid     

  t.timestamps null: false     
end     
add_index :machines, :mid     
end     
end          

机器控制器导入

 def import     
 count = Machine.import(params[:file])     
 redirect_to machines_path, notice: "file imported successfully!"     
 end      

结果控制器导入

 def import      
 count = Result.import params[:file]     
 redirect_to results_path, notice: "file imported successfully!"     
 end     

我想也许我可以将CSV保存到Tempfile然后将值分配给数据库但是跳过条件会覆盖它吗?

另一个解决方案出现在我的脑海中has_many_through,但我真的不知道它会起作用。

1 个答案:

答案 0 :(得分:0)

我能够解决问题

它还不完美,但它导入了一些重要的数据

以下是修改后的结果模型代码

require 'csv'     
class Result < ActiveRecord::Base     
belongs_to :machine     
def self.assign_row(row)    
    line, b, time, real, min, mean, max = row    
    if row[3] =~ /SUMMARY/      
   @midr = row[2].slice(1,3)      
   @mach = Machine.where(:mid => @midr).first      
   @result = Result.create(midr: time, machine_id: @mach.id  )     
  else      
   line, b, time, real, min, mean, max = row      
   @result.update( exps: real, max: max, ideal: mean, time: time  )     
      end      
  end     
 def self.import(file)     
 CSV.foreach(file.path, encoding: 'iso-8859-1:utf-8', skip_blanks: true) do |row|       
next if row.all?(&:nil?)      
result = Result.assign_row(row)     
       end     
  end     
end