有没有想过重构方法self.import_data
的代码?它是一种允许应用程序将CSV文件保存在数据库中的方法(对用户电子邮件有一些限制)。它应该每天中午运行,所以它必须很快。
目前,当我有一个大的CSV文件时它很长。我想知道是否有办法使这个代码更有效并赢得一些时间(或避免循环或减少请求...)。我真的不知道是什么让这个过程如此长,以及如何纠正它。
这是我的模特:
class Person < ActiveRecord::Base
has_paper_trail
validates :email, uniqueness: true
require 'csv'
def is_former_email?(update_email)
self.versions.each do |version|
next if version.object.nil?
return true if version.object.include?(update_email)
end
end
def self.import_data
filename = File.join Rails.root, '/vendor/people.csv'
CSV.foreach(filename, headers: true, col_sep: ',') do |row|
firstname, lastname, home_phone_number, mobile_phone_number, email, address = row
person = Person.find_or_create_by(firstname: row["firstname"], lastname: row['lastname'], address: row['address'] )
if person.is_former_email?(row['email']) == true
puts "not allowed"
else
person.update_attributes({firstname: row['firstname'], lastname: row['lastname'], home_phone_number: row['home_phone_number'], mobile_phone_number: row['mobile_phone_number'], address: row['address'], email: row['email']})
end
end
end
end
答案 0 :(得分:2)
我对您的代码进行了一些重构,但为了更有效率,我建议使用gem activerecord-import并优化版本模型以搜索以前的电子邮件。
class Person < ActiveRecord::Base
require 'csv'
FILE_NAME = File.join Rails.root, '/vendor/people.csv'
validates :email, uniqueness: true
has_paper_trail
def self.import_data
people = CSV.new(File.new(FILE_NAME), headers: true, header_converters: :symbol, converters: :all).to_a.map(&:to_hash)
versions_by_item_id = Version.where(item_type: 'Person').select('item_id, object').group_by(&:item_id)
people.each do |person_params|
person = Person.find_or_create_by(person_params.slice(:firstname, :lastname, :address))
if versions_by_item_id[person.id] && versions_by_item_id[person.id].sum { |v| v.object.to_s }.include?(person_params[:email])
puts 'not allowed'
else
person.update_attributes(person_params.slice(:home_phone_number, :mobile_phone_number, :email))
end
end
end
end