Sử dụng gem Cloudinary để quản lý ảnh
1. Giới thiệu Khi chúng ta tạo một ứng dụng Web bằng Rails và deploy lên Heroku, có một vấn đề mà chúng ta hay gặp phải đó là làm thế nào để tải ảnh lên Heroku. Dẫn link ảnh về là một cách, nhưng với một ảnh mà chúng ta đã mất công sửa, chúng ta lại phải upload ảnh lên một dịch vụ lưu trữ trên ...
1. Giới thiệu
Khi chúng ta tạo một ứng dụng Web bằng Rails và deploy lên Heroku, có một vấn đề mà chúng ta hay gặp phải đó là làm thế nào để tải ảnh lên Heroku. Dẫn link ảnh về là một cách, nhưng với một ảnh mà chúng ta đã mất công sửa, chúng ta lại phải upload ảnh lên một dịch vụ lưu trữ trên mây nào đấy, như Google Drive chẳng hạn. Điều này khá phức tạp. Một giải pháp đơn giản hơn cho vấn đề này là sử dụng gem cloudinary.
Cloudinary cung cấp dịch vụ quản lý ảnh dựa trên cloud một cách toàn diện. Vì vậy bạn có thể upload, lưu trữ, sửa ảnh và đưa nó lên ứng dụng Web của mình một cách dễ dàng. Cloudinary còn được tích hợp rất tốt với nhiều ngôn ngữ và framework khác nhau, trong đó có Ruby on Rails. Cloudinary có nhiều gói dịch vụ khác nhau, trong đó gói free cho phép upload khoảng 75000 ảnh.
Ở bài viết này, mình sẽ hướng dẫn cách tích hợp Cloudinary với Rails
2. Các bước thực hiện
2.1 Cài đặt
Thêm gem cloudinary vào trong Gemfile và chạy bundle
gem "cloudinary"
2.2 Cấu hình
Đăng ký tài khoản và đăng nhập tại đây.
Sau khi đăng nhập và vào dashboard, bạn hãy download file cloudinary.yml tại đây và đưa vào trong thư mục config.
Đây là một ví dụ về file cloudinary.yml:
production: cloud_name: "sample" api_key: "874837483274837" api_secret: "a676b67565c6767a6767d6767f676fe1"
cloud_name được sử dụng để xây dựng URL cho ảnh của bạn. Ngoài ra, api_key và api_secret cần thiết để có thể gọi đến API của Cloudinary.
2.3 Upload ảnh
- Upload từ bên server
Sử dụng method dưới đây để upload ảnh lên cloud:
Cloudinary::Uploader.upload(file, options = {})
Ví dụ:
def index upload_images render end private def local_image_path(name) Rails.root.join("uploads", name).to_s end def upload_images @uploads = {} @uploads[:pizza] = Cloudinary::Uploader.upload local_image_path("pizza.jpg"), :tags => "basic_sample" end
- Upload trực tiếp từ trình duyệt
Việc upload ảnh không thông qua server cho phép việc upload diễn ra nhanh hơn và cung cấp trải nghiệm tốt hơn cho người dùng. Ngoài ra nó cũng giảm tải cho server và giảm độ phức tạp cho ứng dụng của bạn. Cloudinary thực hiện điều này thông qua jQuery
Cài môi trường upload trực tiếp
application.js //= require cloudinary in your view or layout <%= cloudinary_js_config %>
Sử dụng thẻ input cl_image_upload_tag trong form để upload ảnh trực tiếp lên cloudinary.
<%= form_tag(some_path, :method => :post) do %> <%= cl_image_upload_tag(:image_id) %> ... <% end %>
2.4 Thao tác với ảnh
- Hiển thị ảnh
Sử dụng cl_image_tag để thay cho image_tag
cl_image_tag("sample.jpg", :alt => "Sample Image")
- Resize, crop
cl_image_tag("sample.jpg", :awidth => 100, :height => 150, :crop => :fill)
2.5 Kết hợp với CarrierWave
CarrierWave là một gem nổi tiếng trong việc upload file và ảnh. Việc kết hợp CarrierWave và Cloudinary đem lại tiện ích của cả hai: dễ dàng upload ảnh từ form trên HTML đến model, đồng thời có thể lưu và sửa ảnh trên cloud.
Trước tiên chúng ta thêm trong Gemfile và bundle
gem "carrierwave" gem "cloudinary"
Cài đặt CarrierWave theo hướng dẫn tại đây . Sau khi viết uploader class của CarrierWave thì ta thêm plugin Cloudinary vào và chỉnh sửa form.
/app/uploaders/post_uploader.rb class PictureUploader < CarrierWave::Uploader::Base include Cloudinary::CarrierWave process :convert => 'png' process :tags => ['post_picture'] version :standard do process :resize_to_fill => [100, 150, :north] end version :thumbnail do resize_to_fit(50, 50) end end /app/models/post.rb class Post < ActiveRecord::Base mount_uploader :picture, PictureUploader ... end /app/views/posts/edit.html.erb ... <%= form_for :post do |post_form| %> ... <% post_form.hidden_field :picture_cache %> <% post_form.file_field :picture %> ... /app/controllers/posts_controller.rb ... def update post.update_attributes post_params ... end private def category_params params.require(:post).permit :picture, :picture_cache end
Chúng ta đã thực hiện xong việc tích hợp Cloudinary và Rails, bao gồm cả việc kết hợp CarrierWave và Cloudinary.
Bài viết còn nhiều hạn chế, nhưng mình hy vọng bài này có thể giúp mọi người biết thêm một công cụ mới để quản lý ảnh cho ứng dụng của mình.