我正在尝试使用每日RAKE任务将我的应用中的用户表与CSV文件同步。
我的import.rake任务成功导入了表中找不到的记录(find_or_create_by_username),但我不知道如何从表中删除CSV文件中不再存在的记录。我应该使用什么而不是“find_or_create_by_username”来实现这一目标?提前谢谢。
#lib/tasks/import.rake
desc "Import employees from csv file"
task :import => [:environment] do
file = "db/testusers.csv"
usernames = [] # make an array to collect names
CSV.foreach(file, headers: true) do |row|
Employee.find_or_create_by_username({
# Add this line:
username = row[0]
:username => username,
:last_name => row[1],
:first_name => row[2],
:employee_number => row[3],
:phone => row[4],
:mail_station => row[5]
}
)
# Collect the usernames
usernames << username
end
# Delete the employees (make sure you fire them first)
Employee.where.not( username: usernames ).destroy_all
end
答案 0 :(得分:1)
您可以通过执行以下操作来实现此目的:
#lib/tasks/import.rake
require 'csv'
desc "Import employees from csv file"
task :import => [:environment] do
file = "db/users.csv"
employee_ids_to_keep = []
CSV.foreach(file, headers: true) do |row|
attrs = {
:username => row[0], :last_name => row[1], :first_name => row[2],
:employee_number => row[3], :phone => row[4],:mail_station => row[5]
}
# retrieves the Employee with username
employee = Employee.where(username: attrs[:username]).first
if employee.present? # updates the user's attributes if exists
employee.update_attributes(attrs)
else # creates the Employee if does not exist in the DB
employee = Employee.create!(attrs)
end
# keeps the ID of the employee to not destroy it
employee_ids_to_keep << employee.id
end
Employee.where('employees.id NOT IN (?)', employee_ids_to_keep).destroy_all
end
答案 1 :(得分:0)
获取数据库中所有ID的列表,并将它们存储在一个集合中。然后,在进行导入时,从集合中删除有效的员工。完成后,需要从数据库中删除集合中剩余的任何ID。
像这样......
existing_ids = Employee.pluck(:id).to_set
CSV.foreach(file, headers: true) do |row|
employee = Employee.find_or_create_by.....
existing_ids.delete(employee.id)
end
Employee.destroy(*existing_ids.to_a) unless existing_ids.empty?
答案 2 :(得分:0)
usernames = [] # make an array to collect names
CSV.foreach(file, headers: true) do |row|
username = row[0]
Employee.find_or_create_by_username({
:username => username,
:last_name => row[1],
:first_name => row[2],
:employee_number => row[3],
:phone => row[4],
:mail_station => row[5]
}
)
# Collect the usernames
usernames << username
end
# Delete the employees (make sure you fire them first)
Employee.where.not( username: usernames ).destroy_all
where.not
当然可以使用rails 4。