質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

2回答

1336閲覧

RailsでCSVファイルをインポートしたいが、先頭列だけ設定されずエラーになる

magellan

総合スコア17

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2019/01/09 05:52

編集2019/01/09 05:56

前提・実現したいこと

お世話になります。
初投稿です。いろいろご指摘いただけるとありがたいです。
宜しくお願いします。

現在、Ruby on Railsにてwebアプリを開発しております。
ブラウザからCSVファイルを選択して、データをDBにインポートしたいと考えています。

発生している問題・エラーメッセージ

エラーにはなるのですが、エラー原因はわかっています。
CSVファイルの先頭列(Pkey)だけが作成されるInsert文に設定されず、Insertでキー無しでエラーになっています。
質問したいのは、なぜCSVファイルの先頭列の値が設定されないのか。
どうしたら先頭列の値が設定できるのか、ということです。

該当のソースコード

インポートの設定は以下です。

**[app/models/itemmastertest.rb]** class Itemmastertest < ApplicationRecord def self.item_attributes ["itemid","item_name","item_color","abo_flag","remarks","created_at","updated_at"] end def self.import(file) CSV.foreach(file.path, headers:true) do |row| itemmastertest = new itemmastertest.attributes = row.to_hash.slice(*item_attributes) itemmaster.save! end end end **[config/application.rb]** require 'csv' **[app/views/index.html.slim]** = form_tag import_itemmastertests_path, multipart: true, class: 'mb-3' do = file_field_tag :file = submit_tag "インポート", class: 'btn btn-info' **[app/controllers/itemmastertests.controller.rb]** def import Itemmastertest.import(params[:file]) redirect_to itemmastertests_url, notice: "インポート完了!" end

試したこと

csvファイルを読み込むmodelで値が設定されているか検証しました。
foreachの繰り返しの部分で値が設定されているのかを確認しました。
puts row[0]
→ E100
rowの添え字0には値が設定されていました。

puts Itemmastertest.attributes
→ {"id"=>nil, "itemid"=>nil, "item_name"=>"商品1", "item_color"=>"90", "abo_flag"=>true, "remarks"=>nil, "created_at"=>Tue, 08 Jan 2019 00:00:00 UTC +00:00, "updated_at"=>Tue, 08 Jan 2019 00:00:00 UTC +00:00}
上記"id"=>nil はrailsで自動設定される認識ですので問題ないと思っています。
csvファイルの先頭列のitemidには値が設定されていませんでした。

DBのテーブル(model)を再作成し、別のカラムを先頭列にしてみた。
→同じ現象になり、先頭列の値が設定されませんでした。

補足情報(FW/ツールのバージョンなど)

以下、実行環境です。
OS
Windows10 64bit

ruby -v
ruby 2.5.3p105 (2018-10-18 revision 65156) [x64-mingw32]

rails version
Rails 5.2.2

DB
psql (PostgreSQL) 11.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

matsuand

2019/01/10 01:57

(ヘッダー列を含んだ)csv ファイルのサンプルを示してみてください。
magellan

2019/01/10 02:34

matsuand様 お世話になります。 下記がcsvファイルのサンプルです。 宜しくお願いします。 itemid,item_color,item_name,abo_flag,remarks,created_at,updated_at E210,E210 ドライノースリーブシャツ Men's ホワイト,90,TRUE,,2019/1/8,2019/1/8 E211,E211 ドライノースリーブシャツ Lady's ホワイト,90,TRUE,,2019/1/8,2019/1/8 E220,E220 ドライTシャツ サックス,1,TRUE,,2019/1/8,2019/1/8
matsuand

2019/01/10 03:03

ヘッダーのitem_color の順番がおかしいです。
matsuand

2019/01/10 03:25

それから itemid を integer にしてませんか?
magellan

2019/01/10 04:14

matsuand様 item_colorの順番は間違っておりました。 申し訳ありません。 正しくは itemid,item_name,item_color,abo_flag,remarks,created_at,updated_at です。 itemidはtextです。 ちなみにitem_color,item_name,remarksもtextです。 abo_flagはbooleanです。
matsuand

2019/01/10 04:19

あと気になるのは商品名が引用符でくくられていないこと、ファイルエンコーディングが utf か否か、といったところです。
magellan

2019/01/10 04:28

matsuand様 商品名は引用符でくくられていませんが、Itemmastertest.attributesを確認したときに値が設定されていますので問題ないと考えます。 ファイルエンコーディングはutf-8です。 よろしくお願いします。
matsuand

2019/01/10 05:11

私は CSVインポート部分についてのみ確認しています。rails console により、f=File.open("xxx.csv")、Itemmastertest.import(f) で正常登録されます。対象ファイルの誤認、import実行の誤認、など、お示しになっていない部分での誤りがあるとしか、今のところ考えられません。
magellan

2019/01/10 07:16

matsuand様 同じ方法でコンソールから実行してみましたが、やっぱり駄目でした。 同じことしてるんですから当たり前なんですが…。 matsuand様がやってみて正常登録されるということは、やはりどこかプログラムがおかしいのですね。 根気よく頑張ってみます。 ありがとうございました。
matsuand

2019/01/10 07:40

書き忘れていましたが、タイポありましたよ: × itemmaster.save! ○ itemmastertest.save!
magellan

2019/01/11 02:57

matsuand様 タイポのご指摘ありがとうございます。 自己解決できました。 いろいろとありがとうございました。
guest

回答2

0

自己解決

はじめに、matuand様、yuinyan様、いろいろ考えていただきありがとうございました。
エクスポートしたデータをちょっと変えてインポートしたところ、正常にインサートできました。
手作成したデータと見た目は何も変わらなかったのですが、違いはBOMが付いているかいないかの違いでした。

私が手作成したデータにはBOMが付いており、エクスポートしたデータにはBOMが付いておりませんでした。
手作成したCSVデータからBOMを外してインポートしたところ、正常にインサートできました。

先頭列にBOMが付いていたのでカラム名を正常に認識できず、データを取り込めなかったと思います。
勉強不足で申し訳ありません。
本当にありがとうございました。

投稿2019/01/11 03:04

magellan

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ご質問の意味を正しく理解できていないかもしれませんが、headersオプションを使うと、CSVの初めの1行はheaderとして無視されます。今回はこのオプションを使っていますが、headerがないときはこのオプションはいりません。
先頭列と言っているのは、先頭行のことでしょうか?

投稿2019/01/09 15:16

Yuinyan

総合スコア312

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

magellan

2019/01/09 23:33

Yuinyan様 ご回答ありがとうございます。 先頭行ではなく、列なのです。 csvファイルをエクセルで開いたときのA列です。 各行の1つめのデータです。 うまく説明できなくて申し訳ありません。 イメージ的には AAA,BBB,CCC DDD,EEE,FFF と、あるcsvファイルを読み込んで、 1行目はAAAが、2行目はDDDが取得できません。 質問でいうitemidがそれにあたります。 宜しくお願いします。
Yuinyan

2019/01/10 02:30

そうでしたか。ここには表示されていませんが、CSV側の問題がありそうな気がしますが、いかがでしょう。推測で申し訳ありませんが。
magellan

2019/01/10 02:42

Yuinyan様 参考書を一通りやった時は何の問題もなくできていました。 その時は登録したデータをエクスポートして、編集し、インポートしたと思います。 作成したcsvファイルが悪いのかもしれません…固定概念を捨てて確認してみます。 csvファイルのサンプルを上げましたので、お時間があれば何でも良いのでご指摘いただけますでしょうか。 宜しくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問