4

アップロードされた CSV ファイルがあり、次のように解析します。

CSV.foreach(@my_file.file.path) do |row|
    puts row[1]
end

受信 CSV ファイルには、少なくとも「id」、「name」、「number」、「phone」、および「food」の列があります。

私は次のようなことをしたいと思います:

CSV.foreach(@my_file.file.path) do |row|
     //find the columns in "row" associated with "id", "name", "number"
     //even though I don't know definitively which column they will be in
     //for example, "name" may be the 2nd or 3rd or 4th column (etc)

     //insert into my_table values(id, name, number)

end

CSV ファイルの最初の行は常に列名ですが、ファイルごとに列の順序が異なる場合があることに注意してください。

4

2 に答える 2

9

関心のあるフィールドのみをハッシュの配列に収集するコードのスニペットを次に示します。

require 'csv'

fields_to_insert = %w{ id name food number phone }
rows_to_insert = []

CSV.foreach("stuff.csv", headers: true) do |row|
  row_to_insert = row.to_hash.select { |k, v| fields_to_insert.include?(k) }
  rows_to_insert << row_to_insert
end

の次の内容が与えられた場合stuff.csv:

junk1,name,junk2,food,id,junk4,number,phone
foo,Jim,bar,pizza,123,baz,9,555-1212
baz,Fred,bar,sushi,55,foo,44,555-1213

rows_to_insert含まれます:

[{"name"=>"Jim",
  "food"=>"pizza",
  "id"=>"123",
  "number"=>"9",
  "phone"=>"555-1212"},
 {"name"=>"Fred",
  "food"=>"sushi",
  "id"=>"55",
  "number"=>"44",
  "phone"=>"555-1213"}]

私はそれを取り、activerecord-importを使用してそれらを一度にすべて挿入します。

SomeModel.import(rows_to_insert)

一度に 1 つずつレコードを CSV ループに挿入することもできますが、それは非効率的です。また、id通常は保護された属性であるため、大量に割り当てることはできないため、単一のレコードを挿入するには次のようにする必要があります。

some_model = SomeModel.new(row_to_insert.select { |k, v| k != "id" }
some_model.id = row_to_insert["id"]
some_model.save!

...または似たようなもの。

于 2013-04-01T21:45:50.800 に答える