[Rails] 上傳圖片功能 - via CarrierWave

上傳圖片功能 - via CarrierWave

目的

  一個網站在許多地方都需要上傳圖片或照片的功能,例如大頭貼(Avatar)或是商品照片等,而在 rails 中我們有現成的 gem可以使用,你可以使用 paperclipCarrierWave 來實作這個功能,這邊就筆記一下怎麼使用 CarrierWave。

前言

  從完全沒寫過 web app 直接學習 Ruby on Rails,說實在真有點勉強…但接觸 RoR 後我發現這真的是我喜歡的東西,希望能保持這個初衷和熱情!也期待自己能有更多的作品 ccc

筆記

1. Gem

 先添加 gem 到 Gemfile 中

Gemfile
1
2
gem 'carrierwave', '~> 0.10.0'
gem 'rmagick' , '~> 2.15' # 使用 rmagick 作縮放圖片功能

then,

1
bundle install

【提醒】安裝 rmagick 前得先安裝 libmagickwand-dev。
    由於我的環境是 Ubuntu 15.04,所以透過 sudo apt-get install libmagickwand-dev 安裝

2. 生成 Uploader

 bundle install 後,可以在 rails g -h 看到新增了 uploader,接著

1
rails g uploader Iamge # 會生成 app/uploaders/image_uploader.rb

3. 添加欄位

 在想要上傳圖片的資料表中添加對應的欄位

1
rails g migration add_image_to_users image:string # 此例為添加一欄位(image)至 User 中

then, 記得 migrate

1
rake db:migrate

4. 實作上傳及顯示功能

 首先在 model 中掛載 uploader

app/models/user.rb
1
mount_uploader :image, ImageUploader

 接著 view 即可作上傳跟顯示,以下為上傳、快取、刪除跟顯示的作法

app/views/users/new.html.erb
1
2
3
4
5
6
<%= simple_form_for @user do |f| %>
 <%= f.input :image %> <!-- 上傳 -->
 <%= f.check_box :remove_image %> <!-- 刪除 -->
 <%= f.hidden_field :image_cache %> <!-- 快取 _cache (讓填表時若有誤,不用重新選擇圖片) -->
 <%= image_tag @user.image if @user.image? %> <!-- 如果 user 已有圖片的話,就顯示 -->
<% end %>

 最後,controller 中記得加入 strong params

app/controllers/users_controller.rb
1
params.require(:user).permit( :image, :image_cache, :remove_image)

 以上,就完成用 CarrierWave 上傳圖片及顯示的功能囉!但,上傳後圖片大小為原始大小,所以我們可以透過 rmagick 來作 resize。

5. 使用 rmagick

 首先在 image_uploader.rb 中取消註解:

app/uploaders/image_uploader.rb
1
2
3
4
include CarrierWave::RMagick # 取消註解
version :thumb do
process :resize_to_fit => [200, 200]
end

 上面透過 thumb,讓上傳時保存原圖,並且產生一個 resize version,這樣想用原圖縮放後的版本都很方便!

app/views/users/show.html.erb
1
2
3
4
<!-- 原圖尺寸 -->
<%= image_tag @user.image %>
<!-- 縮放後尺寸 -->
<%= image_tag @user.image_url(:thumb) %>

 從上面可看到,從 _url(:thumb) 即可取得縮放後的圖片了!

That’s it, DONE!

【參考資料】