Upload image với gem CarrierWave
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 ...
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