carriverwave multiple file upload with sql3 多圖上傳

最近要拿carriverwave來做圖片上傳,跟著官方的教學跑還踩了一大堆的雷,所以怨念有點深了來紀錄一下怎麼用warriverwave做多圖上傳。
前面先容我廢話一下
在官方文件裡講到要用這個功能db欄位必須支援能儲存array或是json,BUT!!我是用sql3阿,然後官方文件裡又沒說要怎麼用sql3使用多圖上傳,這一個地方就是我最幹的地方,害我在這個地方卡了八個小時!!最後才在ruby china的這篇关于 CarrierWave 的 Multiple file uploads發現有人有一樣的問題,在uploader物件產生的時候,的確可以取到欄位裡多張圖片的資訊,照理說用p.images[0].url or p.images[1].url就可以取到不同圖片的路徑,但實際寫到db裡後因為欄位不支援array or json所以當要取資料的時後,就沒辦法用array的方式取然後就變成所有圖片得資料都塞成一個字串,想要切字還沒辦法切

p.images[0].url
=>""/uploads/photo/images/40/medium_%5B%22Broken_Top.jpg%22%2C%20%22Bridge.jpg%22%5D""

p.images[1].url
=>nil

最後才去翻他官方的issue才發現原來老早就有人提出這個問題並且說出解決方法,還建議官方把解法放在官方文件裡,但官方說

This may work, but I don't think it should be documented as officially supported. It's currently targeting PostgreSQL and should work with MySQL 5.7, which has native JSON columns.

去死拉!!害我卡在這邊八小時,原文在此Updated Readme with note about array column
靠北完了開始正題

安裝gem

在官方文件裡有寫到要做多圖上傳的話必須安裝特定master branch的cariverwave
gem 'carrierwave', github: 'carrierwaveuploader/carrierwave'

安裝carriverwave

rails generate uploader Image
rails g model photo images:string #建立一個叫做images的欄位(複數),欄位屬性是string
rake db:migrate

設定model

這邊有幾點要注意的是
1.mount_uploaders是複數。
2.mount_uploaders後面的:images就是你建立model時所建立的table欄位的名稱,這邊也複數因為裡面會有多筆資料。
3.最後面的ImageUploader是上面用rails generate uploader Image所以才叫這個名稱,如果是用rails generate uploader abc那後面的uploader就會叫做AbcUploader
4.重點中的重點!!要加上serialize :images這樣才有辦法在string column用array的方式查詢到資料,如果沒加的話不僅查不到資料,資料刪除時圖片都不會跟著刪除請注意!!

app.model/photo.rb
class Photo < ActiveRecord::Base
  mount_uploaders :images, ImageUploader
  serialize :images#重點!重點!重點!很重要所以講三次,因為官方不講

end

設定form

記得用file_field,然後加上multiple: true

<%= form.file_field :images, multiple: true %>

設定strong parameters

加上{images: []}記得要用{}包住

params.require(:photo).permit(:art, {images: []})

query資料

之後就可以試一下選擇多個檔案上傳,要取資料的時候可以用

controller.rb
p = Photo.last
p.images[0].url
p.images[1].url

的方式取得不同圖片的路徑。

有興趣的人可以clone專案來看看

參考資料:
http://stackoverflow.com/questions/21411988/rails-4-multiple-image-or-file-upload-using-carrierwave
https://github.com/carrierwaveuploader/carrierwave#multiple-file-uploads

comments powered by Disqus