昨天說的是單一檔案上傳,如果要多個檔案上傳的話...
資料表先新增可以儲存一個陣列的欄位。這個資料型態可以是 Array 或者 JSON。
不過選擇哪種資料型態會取決於你使用哪個資料庫。因為有些資料不支援 JSON( 例:SQLite )
有支援 JSON 格式的資料庫有 PostgreSQL、MySQL,建立專案時,已經設定過 database 為 PostgreSQL,所以這邊就用 JSON 格式來設定欄位型態:
$ rails g migration add_avatars_to_profiles avatars:json
$ rails db:migrate
因為這次要上傳多個檔案,所以用複數,mount_uploaders、:avatars 都要加上 s
# app/models/profile.rb
class User < ActiveRecord::Base
mount_uploaders :avatars, AvatarUploader
end
# profiles_controller.rb
def profile_params
params.require(:profile).permit(:nickname, :email, {avatars: []})
end
請注意,多個檔案上傳,儲存的方式是陣列,所以在通過清洗的時候,要賦予一個空陣列的資料型態!
資料庫的table儲存的樣子:["apple.png", "orange.png", "banana.jpg"]
<%= form.file_field :avatars, multiple: true %>
這樣就可以選取多個檔案!
如果要在上傳新檔案時,保留目前現有檔案的話,可以改成這段:
<% profile.avatars.each do |avatar| %>
<%= hidden_field :profile, :avatars, multiple: true, value: avatar.identifier %>
<% end %>
<%= form.file_field :avatars, multiple: true %>
小補充:
profile.avatars[0].url
# 印出 '/url/to/file.jpg' 圖片的相對路徑
profile.avatars[0].current_path
# 印出 'path/to/file.jpg' 圖片的絕對路徑
profile.avatars[0].identifier
# 印出 'file.jpg' 圖片的檔名
profile.avatars[0].file.nil?
# 判斷檔案是否存在
為了避免有心人士或使用者不小心上傳錯誤的文件,造成危險,例如:php 檔案或其他腳本文件。CarrierWave 可以讓你指定允許的檔案類型存取。
白名單寫法,在名單中的才可以通過:
# avatar_uploader.rb
class AvatarUploader < CarrierWave::Uploader::Base
def extension_whitelist
%w(jpg jpeg gif png)
end
end
黑名單寫法,在名單中的會被拒絕存入:
假設我們拒絕 JSON 的檔案
class NoJsonUploader < CarrierWave::Uploader::Base
def content_type_blacklist
['application/text', 'application/json']
end
end
參考資料:
GitHub - CarrierWave
PJCHENder未整理筆記
學無止盡,每天都要進步一點點!