Upload image với gem CarrierWave
Bài đăng này đã không được cập nhật trong 9 năm
Gem CarrierWave hỗ trợ upload tập tin và hình ảnh một cách đơn giản và linh hoạt đối với các ứng dụng Ruby.
- Cài đặt:
Cũng như các gem khác, để cài đặt chúng ta thêm gem CarrierWave vào trong Gemfile
và sau đó bundle install
.
gem 'carrierwave'
- Để hiểu rõ về phương thức hoạt động và cách sử dụng của gem carrierwave chúng ta sẽ đi vào làm một ví dụ xây dựng 1 web cho phép người dùng tự tạo album, upload photo vào album đó.
Database:
create_table "albums", force: true do |t|
t.string "name"
end
create_table "photos", force: true do |t|
t.string "name"
t.integer "album_id"
end
- CarrierWave cung cấp 1 thư viện
uploader
. Để sử dụng thư viện này ta generate, dùng câu lệnh trong Terminal:
$ rails generate uploader image
create app/uploaders/image_uploader.rb
Kiểm tra trong thử mục app/uploaders
xuất hiện file image_uploader.rb
.
class ImageUploader < CarrierWave::Uploader::Base
storage :file
end
Tiếp theo chúng ta kết nối image với model Photo (mỗi photo thì có file image tương ứng). Thêm thuộc tính image vào bảng Photo:
$ rails g migration add_image_to_photos image:string
Mở file /app/models/photo.rb
thêm các attr_accessible
, quan hệ belongs_to đối với album và liên kết image với ImageUploader
:
class Photo < ActiveRecord::Base
attr_accessible :album_id, :name, :image
belongs_to :album
mount_uploader :image, ImageUploader
end
Trong file view chúng ta sử dụng form_for cho @photo, thêm :html => {:multipart => true} để có thể upload file.
<%= form_for @photo, :html => {:multipart => true} do |f| %>
<%= f.error_messages %>
<%= f.hidden_field :album_id %>
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>
<p>
<%= f.file_field :image %>
</p>
<p><%= f.submit %></p>
<% end %>
Để hiển thị hình ảnh ra màn hình, chúng ta có thể sử dụng image_tag với link của photo là image_url
, thêm to_s để tránh trường hợp không có ảnh giá trị trả về sẽ là nil:
<%= image_tag photo.image_url.to_s %>
- Tuy nhiên, nếu để thế này thì ảnh sẽ được hiển thị ở cỡ thực có thể to quá hoặc bé quá.
ImageUploader
có thể giúp chúng ta vẫn giữ ảnh gốc và sao lưu ra các phiên bản ảnh khác với các kích thước chúng ta mong muốn.
Cài đặt thêm gem mini_magick
vào Gemfile để có thể thay đổi kích thước của ảnh (một số tài liệu hướng dẫn có thể thêm gem rmagick
).
Trong image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
process resize_to_fit: [800, 800]
version :thumb do
process resize_to_fill: [200,200]
end
end
Khi ảnh được tải lên, giá trị kích thước mặc định là chiều dài, chiều rộng không quá 800px. Còn version thumb, ảnh được tải lên và crop về size 200px, 200px. Có thể tạo nhiều version.
photo.url # size: 800x800
uploader.thumb.url # size: 200x200
- Ở trên là cách upload ảnh có sẵn trong máy tính, chúng ta cũng có thể upload bằng
url
của ảnh.
Trong model photo.rb
thêm attr_accessible :remote_image_url
.
File view, trong form_for thêm
<p>
<%= f.label :remote_image_url, "upload by image URL" %>
<%= f.text_field :remote_image_url %>
</p>
Chúng ta chỉ việc paste link và ảnh được tải lên 1 cách dễ dàng.
- Để xoá file ảnh, ta chỉ cần gọi method
remove_image
sau đó save.
<%= f.check_box :remove_image %>Xóa ảnh
@photo.remove_image!
@photo.save
#=> true
- CarrierWave còn cho phép người dùng giới hạn kiểu file nhất định để được tải lên.
class ImageUploader < CarrierWave::Uploader::Base
def extension_white_list
%w(jpg jpeg gif png)
end
end
Phía trên là người dùng chỉ được phép tải ảnh có đuôi là : .jpg, .jpeg, .gif hoặc .png
- Trong trường hợp ảnh tải lên bị lỗi, carrierwave cũng hỗ trợ xác định các url mặc định để thay thế:
image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
def default_url(*args)
'/images/fallback/' + [version_name, 'default.png'].compact.join('_')
end
end
Kết: Với Gem CarrierWave việc upload ảnh trở nên thật dễ dàng . Ngoài ra còn có các gem Paperclip, Dragonfly,...
Tài liệu tham khảo:
All rights reserved