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", :width => 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.