如果User存在更新变量,则为Create new(find_or_create_by)

时间:2014-05-06 17:04:12

标签: ruby-on-rails ruby csv import

我正在从CSV文件导入数据(使用Smarter CSV)。我在任务中处理此文件如下:

require 'smarter_csv'

desc "Import Players from World data"

task :import => [:environment] do

  file = "db/data/players.txt"

  SmarterCSV.process(file, {
    :user_provided_headers => [
      "grepo_id", "name", "alliance_id", "points", "rank", "towns"
    ], headers_in_file: false
  }) do |array|

    # post-process the data from each row
    array.each do |a|
      a[:name] = CGI::unescape(a[:name]).force_encoding('UTF-8')
    end

    # Create Player
    Player.create(array.first)

  end

end

:user_provided_headers你可以看到传递给每个玩家的变量。

变量'grepo_id''name'始终保持不变,但其他变量会随着时间的推移而变化。

我正在尝试给定用户Find_or_createUpdate。对于引用用户,我使用'grepo_id',因为此变量对每个玩家都是唯一的。

但似乎我错过了一些东西,无论我尝试去游泳,我想我在这里采取了错误的方法。

在这种情况下我能做些什么:

  • Find_by 'grepo_id'
  • 如果存在更新其他变量(如果有任何更改)
  • 如果不存在,请创建。

干杯

编辑:来自智慧CSV文档

SmarterCSV.process(filename) do |array|
  # we're passing a block in, to process each resulting hash / =row (the block takes array of hashes)
  # there is only one hash in each array
  MyModel.create( array.first )
end

1 个答案:

答案 0 :(得分:1)

试试这个 - 我假设你想要为这里的所有行而不是第一行,但如果情况并非如此,你可以改变

@users = []
array.each do |row|
  row[:name] = CGI::unescape(row[:name]).force_encoding('UTF-8')
  user = User.find_by_grepo_id(row[:grepo_id]) || User.new
  user.update_attributes(row)
  @users << user
end