Upload image using Carrierwave
Bài đăng này đã không được cập nhật trong 8 năm
Carrierwave là một trong nhưng gem mà có thể giúp các bạn upload file lên server như Paperclip, Dragonfly, Shrine … Nhưng mình thích Carrierwave bởi nó có rất nhiều tính năng và cũng dễ sử dụng nữa. Trong bài viết này mình sẽ giới thiệu với các bạn một cách tổng quát về cách sử dụng carierwave.
Tạo một application Demo
Như mọi bài mình sẽ tạo một app demo giúp các bạn có thể follow dễ dàng hơn
rails new demo
Tiếp theo chúng ta tạo một model Post trong đó có các thuộc tính title, body, image
rails g model Post title:string body:text image:string
Sau khi hoàn tất bạn chạy rake db:migrate nhé
Tiếp theo mình sẽ tạo một controllers và view cho post posts_controller.rb
class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update]
 
  def index
    @posts = Post.order "created_at DESC"
  end
 
  def show
  end
 
  def new
    @post = Post.new
  end
 
  def create
    @post = Post.new post_params
    if @post.save
      redirect_to posts_path
    else
      render :new
    end
  end
 
  def edit
  end
 
  def update
    if @post.update_attributes(post_params)
      redirect_to post_path(@post)
    else
      render :edit
    end
  end
 
  private
 
  def post_params
    params.require(:post).permit :title, :body, :image
  end
 
  def set_post
    @post = Post.find_by params[:id]
  end
end
views/posts/index.html.erb
<h1>Posts</h1>
 
<%= link_to "Add post", new_post_path %>
 
<%= render @posts %>
views/posts/_post.html.erb
<h2><%= link_to post.title, post_path post  %></h2>
 
<p><%= truncate post.body, length: 150 %></p>
 
<p><%= link_to "Edit", edit_post_path post %></p>
<hr>
Config Carrierwave
Trong file Gemfile bạn thêm dòng này vào nhé gem “carrierwave” và chạy bundle install
Carrierwave nó lưu file config trong folder uploader. Trong file này bạn có thể cấu hình rất nhiều thứ ví dự địa chỉ lưu file trên server, validation extension, hay định nghĩa các version image thumn, origin …. Để tạo file này thì bạn dùng lệnh sau
rails generate uploader Image
Một file image_uploader sẽ được tạo trong app/uploaders.
class ImageUploader < CarrierWave::Uploader::Base
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{model.id}"
  end
  def extension_white_list
    %w(jpg jpeg gif png)
  end
end
Ở trong file config mình sẽ định nghĩa nơi lưu file trong hàm store_dir và mình định nghĩa nhưng định dang mà có thể upload được lên server trong hàm extension_white_list
Bước tiếp theo chúng ta phải mount file uploader này vào model .
Model/post.rb
mount_uploader :image, ImageUploader
trong câu lệnh trên thì image là trường db. ImageUploader là class của file uploader. đến đây thôi bạn có thể thao tác vơi image như một trường bình thường. views/posts/new.html.erb
<h1>Add post</h1>
 
<%= render "form", post: @post %>
để tiện cho việc update, create cho app mình sẽ tạo một partial _form.html.erb để tránh việc DRYcode views/posts/_form.html.erb
<%= form_for post do |f| %>
  <div>
    <%= f.label :title %>
    <%= f.text_field :title %>
  </div>
 
  <div>
    <%= f.label :body %>
    <%= f.text_area :body %>
  </div>
 
  <div>
    <%= f.label :image %>
    <%= f.file_field :image %>
  </div>
 
  <%= f.submit %>
<% end %>
views/posts/edit.html.erb
<h1>Edit post</h1>
 
<%= render "form", post: @post %>
views/posts/show.html.erb
<%= link_to "All posts", posts_path %>
<h1><%= @post.title %></h1>
 
<%= image_tag(@post.image.url, alt: "Image") if @post.image? %>
 
<p><%= @post.body %></p>
 
<p><%= link_to "Edit", edit_post_path @post  %></p>
Về cơ bản như vậy là bạn có thể chạy được app rồi . bạn thử khởi động rails s . và vào đường link: localhost:3000/posts để thử nhé
I18N Carrierwave
Đây là nhưng message khi bạn thao tác với carrierwave.bạn có thể thay đổi trong file ja.yml nhé.
errors:
  messages:
    carrierwave_processing_error: "Cannot resize image."
    carrierwave_integrity_error: "Not an image."
    carrierwave_download_error: "Couldn't download image."
    extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
    extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
Một số lệnh trong Console với Carrierwave
Gán ảnh cho một đối tượng
post = Post.first # giả sử  post tồn tại
image = File.open file_path
post.image = image
post.save!
Delete anh của một đối tượng
post.remove_image!
post.save
post.reload
post.image?
 >> nil
lấy path file storage
post.image.path
Kiểm tra đối tượng có image hay không
post.image?
Conclusion
Trên đây mình đã giới thiệu gem Carrierwave cách sử dụng và tùy biến. Hy vọng sẽ giúp ích được bạn 
All rights reserved
 
  
 