1

我正在尝试使用每日 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
4

3 回答 3

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
于 2013-09-17T20:59:40.853 回答
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。

于 2013-09-17T20:53:49.407 回答
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?
于 2013-09-17T20:47:50.913 回答