質問編集履歴

1 markdownが乱れてしまったので

kotarokun

kotarokun score 6

2018/04/08 19:11  投稿

Rails + CarrierwaveでJSON APIを作成し、複数画像を登録したい
### 前提・実現したいこと
- 当方初心者なので、不足している情報などあるかもしれませんが、ご容赦ください。必要な情報があれば補足させていただきます。
- 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
#### 送っている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を使っていますが、今回は開発環境でまず失敗しています
  • Ruby

    15878 questions

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

  • Ruby on Rails

    17034 questions

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

  • Ruby on Rails 5

    5710 questions

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

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る