Upload image using Carrierwave
Bài đăng này đã không được cập nhật trong 7 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