首页 > Ruby/Rails开发 > rails -使用mini_magick和carrierwave进行图片上传

rails -使用mini_magick和carrierwave进行图片上传

2016年5月15日

rails -使用mini_magick和carrierwave进行图片上传

http://luoping0425.iteye.com/blog/1059475

使用mini_magick和carrierwave进行图片上传

相关Gem:
https://github.com/jnicklas/carrierwave
https://github.com/probablycorey/mini_magick

参考实例:https://github.com/diaspora/diaspora/blob/master/app/uploaders/processed_image.rb

示例:用户头像

1. 在项目的Gemfile中添加:

Ruby代码
  1. gem ‘carrierwave’
  2. gem ‘mini_magick’

然后bundle install

如果使用Apache+Passenger,则需要将环境变量传递给passenger
此处应该是查找mini_magick的库
SetEnv PATH /usr/bin:/usr/local/bin,
我们加在apache的项目配置文件中

如:

Ruby代码
  1. <VirtualHost *:80>
  2.   ServerName eva
  3.   DocumentRoot /Users/P.Luo/vhosts/eva/public
  4.   SetEnv RootEnv eva
  5.   RailsEnv development
  6.   RackEnv development
  7.   SetEnv PATH /usr/bin:/usr/local/bin
  8.   <Directory “/Users/P.Luo/vhosts/eva/public”>
  9.     AllowOverride all
  10.     Options -MultiViews
  11.     Allow from all
  12.   </Directory>
  13. </VirtualHost>

参考:http://groups.google.com/group/phusion-passenger/browse_thread/thread/c79eb458c69abd89?pli=1

2. $ rails generate model User nickname:string avatar:string

生成migration、数据表:

Ruby代码
  1. class CreateUsers < ActiveRecord::Migration
  2.   def self.up
  3.     create_table :users do |t|
  4.       t.string :nickname
  5.       t.string :avatar
  6.       t.timestamps
  7.     end
  8.   end
  9.   def self.down
  10.     drop_table :users
  11.   end
  12. end

$ rake db:migration

3. 生成uploader:
$ rails generate uploader Avatar
这样会生成文件:app/uploaders/avatar_uploader.rb

a. 修改头像文件存储位置:

Ruby代码
  1. def store_dir
  2.   “uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}”
  3. end

b. 添加头像版本:

Ruby代码
  1. version :thumb do
  2.   process :resize_to_fill => [50, 50]
  3. end
  4. version :normal do
  5.   process :resize_to_fill => [180, 180]
  6. end
  7. version :original

其中process后面的参数可为:resize_to_fill, resize_to_fit, resize_to_limit,其中resize_to_fill如果图片过大是会将图片截取,resize_to_fit则不会截取,而是通过较长长或宽同比例压缩,resize_to_limit就没有研究了。
最后一个版本versionsuriginal看了一下生成的图片文件,原本就有原大小的文件,所以其实可以不用这个版本。
c. 修改文件名
一般上传的文件名需要修改,此处使用加密原文件名的方法。

Ruby代码
  1. def filename
  2.   if @filename
  3.     Digest::SHA1.hexdigest(original_filename) + File.extname(@filename)
  4.   end
  5. end

此处开始使用的是:
Time.now.to_i.to_s + File.extname(@filename)

发现生成不同版本时会取不同的filename,所以无法使用时间戳或随机数。

4. 修改app/models/user.rb:

Ruby代码
  1. class User < ActiveRecord::Base
  2.   mount_uploader :avatar, AvatarUploader
  3. end

5. 创建用户页面app/views/users/_form.html.erb:

Ruby代码
  1. <%= form_for(@user:html => {:multipart => true }) do |f| %>
  2.   <div class=“field”>
  3.     <%= f.label :nickname %><br />
  4.     <%= f.text_field :nickname %>
  5.   </div>
  6.   <div class=“field”>
  7.     <%= f.label :avatar %><br />
  8.     <%= image_tag(@user.avatar_url(:thumb)) if @user.avatar? %>
  9.     <%= f.file_field :avatar %>
  10.     <%= f.hidden_field :avatar_cache %>
  11.   </div>
  12.   <div class=“field”>
  13.     <%= f.label :remove_avatar %><br />
  14.     <%= f.check_box :remove_avatar %>
  15.     Remove Avatar
  16.   </div>
  17.   <div class=“actions”>
  18.     <%= f.submit %>
  19.   </div>
  20. <% end %>

此处的remove_avatar为单独的删除头像,切不可同时上传头像。

6. 在Controller中,不需做任何处理,只是普通的保存就OK。
一般情况下,我们是上传头像后,直接由后台删除原有的图片文件。自己写的更新是:

Ruby代码
  1. def update
  2.     @user = User.find params[:id]
  3.     if params[:user][:avatar] && @user. avatar
  4.       old_avatar = User.find(params[:id]).avatar  # 重新取user备用
  5.     end
  6.     if @user.update_attributes(params[:user])
  7.       old_avatar.remove! if old_avatar
  8. end
  9.     redirect_to admin_groups_path
  10.   end

这样两次取@user,如果有更新,当保存成功时删除原有图片文件,否则不做处理。

本文的评论功能被关闭了.