Hello, 我是 Weber,一位工程師,斜槓鼓手與行銷顧問。
Rails 開發,每日一套件第 10 天,讓我們一起認識 Rails 開發好用的 30 個套件,建立出自己的常用套件庫吧!
莫名其妙 10 天啦! 先離題一下 ~
當初選這個主題,純粹是抱著好奇心以及想分享的精神,而且覺得自己可以再複習一遍這些套件的文件。
寫著寫著對於怎麼樣算是一個好的套件,也有一點小小心得。
功能方便是基本,文件更要寫的好!
(文件呀~文件~就跟寫文章一樣,囉說又必要呀~)
剛好站在開發的路徑上。
(不一定要是多大多炫的東西,可以只是一個小石頭,但幾乎所有開發者都會路過的小石頭。)
積極回應社群的能力,並持續維護。
(這點可能比較中後期,但好用的開發套件幾乎也都有這樣的特性。)
英文還是鐵打的重要。
(除了國際通用性之外,這條語言護城河已經龐大到難以跨過。)
回歸正題:
CarrierWave
是一款經典的檔案上傳套件。其實網路上,已經有相當多中、英文的介紹。
不過似乎沒有人注意到,它是一個很酷的名字,這可能要有玩無線電的人才會知道。
那離我也有點年代了,我也是讀個霧裡看花,不過可以感覺到是個蠻浪漫的名字,還帶有傳送的意涵。
隨附 wiki 解釋:
At the sending end, the information, in the form of a modulation signal, is applied to an electronic device called a transmitter. In the transmitter, an electronic oscillator generates a sinusoidal alternating current of radio frequency; this is the carrier wave.
至於套件本身的功能,用開宗明義一句話來講:
This gem provides a simple and extremely flexible way to upload files from Ruby applications. It works well with Rack based web applications, such as Ruby on Rails.
簡而言之,又是一個 Rack base 的應用,提供簡單又極度靈活的檔案上傳功能。
起手式 bundle add
:
bundle add carrierwave
接著,我們要先產生一個 uploader,這裡運用官方文件中的範例上傳Avatar,不過其實你可以自由換成其他的,Image、Picture 等,看你的需求:
rails g uploader Avatar
會長出 app/uploaders/avatar_uploader.rb
,這裡一樣,看你 generate 的時候打什麼,檔名的前綴就是什麼。
然後這裡要產生欄位,上傳單一檔案、跟上傳多檔案有點些微不同
rails g migration add_avatar_to_users avatar:string
欄位名稱要加上 s ,且欄位格式是 json
後面 Model 等也要帶複數
rails g migration add_avatars_to_users avatars:json
記得在 Model 中掛入 uploader
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
莫忘 Controller 中加入 permit
def user_params
params.require(:user).permit(:name, :avatar)
end
在 View 中送出表單,會自動將檔案上傳到 ./public/uploads/<fieldName>
資料夾中。
<%= form_with(model: user, local: true) do |form| %>
<div class="field">
<%= form.label :avatar %>
<%= form.file_field :avatar, id: :product_avatar %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
在 View 中可以透過:
product.avatar # 取得圖檔相對路徑
product.avatar.url # 取得圖檔相對路徑(和上面一樣)
product.avatar.current_path # 取得圖檔絕對路徑
product.avatar_identifier # 取得檔名(是用底線 _ )
product.avatar.file.nil? # 判斷檔案是否存在
值得一提的是 product.avatar
永遠不會回傳 nil,即使沒有和它關連的圖片也一樣。
要透過 product.avatar.file.nil?
來檢驗是否有相關連的圖片。
大致上就是這樣子,我們明天見囉!