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

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

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

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

8217閲覧

Railsでcsv形式のみを取り込む方法(それ以外エクセルファイルなどはエラーを出したいです)

glvty83

総合スコア135

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

0クリップ

投稿2016/07/12 01:13

webアプリを作っていて、現在csvファイルを取り込む機能を実装しています。
csvファイルからデータの追加、更新はできるのですが、csv形式以外のファイルの場合はエラーを出したいです。
なかなか、実装のイメージがわかないのでご教示いただけると幸いです.....

$ rails -v Rails 5.0.0

##########ルーティングはcosts/importにpostで送られます

costs/csv.html.slim

ruby

1= form_tag costs_path, method: :post, multipart: true do 2 = file_field_tag :csv_file 3 = submit_tag 'CSV読み込み'

cost.rb

ruby

1class Cost < ActiveRecord::Base 2#csvファイルの内容をDBに登録する 3 def self.import(file) 4 imported_num = 0 5 # #文字コード変換のためにKernel#openとCSV#newを併用 6 # #参考: http://qiita.com/labocho/items/8559576b71642b79df67 7 open(file.path, 'r:cp932:utf-8', undef: :replace) do |f| 8 csv = CSV.new(f, :headers => :first_row) #エラーが出る 9 csv.each do |row| 10 next if row.header_row? 11 12 # #CSVの行情報をHASHに変換 13 table = Hash[[row.headers, row.fields].transpose] 14 15 # #登録済みデータ情報 16 # #登録されてなければ作成 17 cost = find_by(:id => table['id']) 18 if cost.nil? 19 cost = new 20 end 21 22 # #データ情報更新 23 cost.attributes = table.to_hash.slice( 24 *table.to_hash.except(:id, :created_at, :updated_at).keys) 25 26 # #バリデーションokの場合は保存 27 if cost.valid? 28 cost.save! 29 imported_num += 1 30 end 31 end 32 end 33 34 # #更新件数を返却 35 imported_num 36 end 37end

controllers/costs_controller.rb

ruby

1 def import 2 if params[:csv_file].blank? 3 redirect_to action: 'index', error: '読み込むCSVを選択してください' 4 else 5 num = Cost.import(params[:csv_file]) 6 redirect_to action: 'index', notice: "#{ num.to_s }件のデータ情報を追加/更新しました" 7 end 8 end 9

コントローラーで拡張子を判別し、処理していくのかと思っているのですが、具体的にどのコードを書いていけば良いかわかりません....
どんなことでも良いのでヒントいただけると嬉しいです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

original_filenameでチェック、さらに例外の捕捉でチェックしてあげれば、うまくいくように思います。

Ruby

1# controller 2def import 3 if params[:csv_file].present? && 4 params[:cvs_file].original_filename && 5 File.extname(params[:cvs_file].original_filename) == ".csv" # パラメータのoriginal_filenameでチェック 6 # 例外を捕捉してエラーが起きないようにする 7 begin 8 num = Cost.import(params[:csv_file]) 9 redirect_to action: 'index', notice: "#{ num.to_s }件のデータ情報を追加/更新しました" 10 return false # 失敗しなければここまで来る。double render error対策にreturn falseして終了 11 rescue # 途中でエラー(CSVのnewでエラーが起きたら)ここに飛ぶ 12 # 特別な後片付けは必要なさそうなので、そのまま。 13 # エラーの種類が特定できるなら、rescueの引数で切り分けてメッセージをflashに入れるとかのOK 14 end 15 end 16 # パラメータの条件ではねられたり、途中でエラーが起きたりした時はここまで来る 17 redirect_to action: 'index', error: '読み込むCSVを選択してください' 18end

非常にざっくり書いてしまったので、分岐が少なめですが、パラメータチェックや、例外の種類によって分岐させる事で、flashに入れるメッセージを細かく切り分ける事が出来るかと思います。

投稿2016/07/12 03:21

rifuch

総合スコア1901

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

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

glvty83

2016/07/12 05:17

回答いただき、どうもありがとうございました! 例外処理が大変参考になりました。 File.extname(params[:cvs_file].original_filename) == ".csv" で拡張子が判別できるのがわかったので、elsifで分岐処理して解決できました....まだまだ改良の余地はありそうですが.... ```ruby def import if params[:csv_file].blank? redirect_to action: 'index', error: '読み込むCSVを選択してください' elsif File.extname(params[:csv_file].original_filename) != ".csv" redirect_to action: 'index', notice: 'csvファイルのみ読み込み可能です' else num = Cost.import_by_csv(params[:csv_file]) redirect_to action: 'index', notice: "#{ num.to_s }件のデータ情報を追加/更新しました" end end ``` このようにして解決できました。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問