前提・実現したいこと
- 当方初心者なので、不足している情報などあるかもしれませんが、ご容赦ください。必要な情報があれば補足させていただきます。
- Ruby on RailsでJSON APIを作成し、iOSのフロントと連携したアプリケーションを作成
- carrierwaveを使用し、フロントから画像をPOSTし、DBに保存したい
- JSONでデータを送る必要があるので、画像をbase64でエンコーディングし、受け取ったデータを「ActionDispatch::Http::UploadedFile」を利用しアップロードしています。
- メイン画像を1つ登録する「main_picture」と、サブ画像を複数登録する「sub_pictures」というカラムをユーザーテーブルに持っています。
- ユーザーのcreate時(updateなども成功しません)、「main_picture」の登録はできるのですが、「sub_pictures」は登録できず、困っています。
発生している問題・エラーメッセージ
"status": 500, "error": "Internal Server Error", "exception": "#<NoMethodError: undefined method `identifier' for #<Array:0x007fcfc5e534d0>>"
該当のソースコード
ユーザー登録処理
def create @user = User.new(user_params) set_main_picture_conversion(params[:main_picture]) if params[:main_picture].present? set_sub_pictures_conversion(params[:sub_pictures]) if params[:sub_pictures].present? if @user.save log_in @user render :file => "app/views/api/users/create.json.jbuilder", formats: 'json', handlers: 'jbuilder' else render :json => @user.errors.full_messages end end
画像のアップロード処理
def split_base64(uri_str) if uri_str.match(%r{data:(.*?);(.*?),(.*)$}) uri = Hash.new uri[:type] = $1 uri[:encoder] = $2 uri[:data] = $3 uri[:extension] = $1.split('/')[1] return uri else return nil end end def base64_conversion(uri_str) _timestamp = DateTime.now.strftime('%Q') image_data = split_base64(uri_str) image_data_string = image_data[:data] image_data_binary = Base64.decode64(image_data_string) temp_img_file = Tempfile.create(basename = "pic_#{_timestamp}.#{image_data[:extension]}") temp_img_file.binmode temp_img_file << image_data_binary temp_img_file.rewind img_params = {:filename => "pic_#{_timestamp}.#{image_data[:extension]}", :type => image_data[:type], :tempfile => temp_img_file} ActionDispatch::Http::UploadedFile.new(img_params) end
送っているJSON
{ “sub_pictures” : [ ”data:image/png;base64, ‘base64でエンコードされた文字列’ , ”data:image/png;base64, ‘base64でエンコードされた文字列’ ] }
参考にしたサイト
https://github.com/thornebrandt/findbball/blob/master/app/controllers/court_photos_controller.rb
試したこと
デバッガーを仕込んでみました
- 画像のアップロードまではできており、sub_picturesの中身にも入っていました
- ユーザーをsaveする際、identifierがないと怒られてしまっているようです
ググってみました
- 同じようなことで困っている人がいましたが、この人たちはidentifierをみたいだけなのか??
- https://github.com/carrierwaveuploader/carrierwave/issues/2180
- https://github.com/carrierwaveuploader/carrierwave/issues/1581
carrier waveのgithubをみました
- identifierを見るメソッドがあるようですが、ここに記載している通り「.カラム名_identifier」のメソッドを試しましたがうまくいかず。。
- 1つの画像登録で成功したファイルでconsoleで試したところ、「ファイルのインスタンス.identifier」でファイル名が表示されましたが、nilでした(@original_filenameが表示されているという理解をしています)
- https://github.com/carrierwaveuploader/carrierwave
Tempfileについて調べました
- @original_filenameをwriteすればうまくいくかと思いwriteしようとしましたが、うまくいきませんでした
- http://api.rubyonrails.org/classes/ActionDispatch/Http/UploadedFile.html
補足情報(FW/ツールのバージョンなど)
- Ruby : 2.4.0
- Rails:5.1.4
- Carrierwave : 1.2.2
- サーバーはherokuを使っていますが、今回は開発環境でまず失敗しています
あなたの回答
tips
プレビュー