使用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中添加:
gem 'carrierwave'
gem 'mini_magick'
然后bundle install
如果使用Apache+Passenger,则需要将环境变量传递给passenger
此处应该是查找mini_magick的库
SetEnv PATH /usr/bin:/usr/local/bin,
我们加在apache的项目配置文件中
如:
<VirtualHost *:80>
ServerName eva
DocumentRoot /Users/P.Luo/vhosts/eva/public
SetEnv RootEnv eva
RailsEnv development
RackEnv development
SetEnv PATH /usr/bin:/usr/local/bin
<Directory "/Users/P.Luo/vhosts/eva/public">
AllowOverride all
Options -MultiViews
Allow from all
</Directory>
</VirtualHost>
参考:http://groups.google.com/group/phusion-passenger/browse_thread/thread/c79eb458c69abd89?pli=1
2. $ rails generate model User nickname:string avatar:string
生成migration、数据表:
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :nickname
t.string :avatar
t.timestamps
end
end
def self.down
drop_table :users
end
end
$ rake db:migration
3. 生成uploader:
$ rails generate uploader Avatar
这样会生成文件:app/uploaders/avatar_uploader.rb
a. 修改头像文件存储位置:
def store_dir
“uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}”
end
b. 添加头像版本:
version :thumb do
process :resize_to_fill => [50, 50]
end
version :normal do
process :resize_to_fill => [180, 180]
end
version :original
其中process后面的参数可为:resize_to_fill, resize_to_fit, resize_to_limit,其中resize_to_fill如果图片过大是会将图片截取,resize_to_fit则不会截取,而是通过较长长或宽同比例压缩,resize_to_limit就没有研究了。
最后一个版本version
riginal看了一下生成的图片文件,原本就有原大小的文件,所以其实可以不用这个版本。
c. 修改文件名
一般上传的文件名需要修改,此处使用加密原文件名的方法。
def filename
if @filename
Digest::SHA1.hexdigest(original_filename) + File.extname(@filename)
end
end
此处开始使用的是:
Time.now.to_i.to_s + File.extname(@filename)
发现生成不同版本时会取不同的filename,所以无法使用时间戳或随机数。
4. 修改app/models/user.rb:
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
5. 创建用户页面app/views/users/_form.html.erb:
<%= form_for(@user, :html => {:multipart => true }) do |f| %>
<div class="field">
<%= f.label :nickname %><br />
<%= f.text_field :nickname %>
</div>
<div class="field">
<%= f.label :avatar %><br />
<%= image_tag(@user.avatar_url(:thumb)) if @user.avatar? %>
<%= f.file_field :avatar %>
<%= f.hidden_field :avatar_cache %>
</div>
<div class="field">
<%= f.label :remove_avatar %><br />
<%= f.check_box :remove_avatar %>
Remove Avatar
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
此处的remove_avatar为单独的删除头像,切不可同时上传头像。
6. 在Controller中,不需做任何处理,只是普通的保存就OK。
一般情况下,我们是上传头像后,直接由后台删除原有的图片文件。自己写的更新是:
def update
@user = User.find params[:id]
if params[:user][:avatar] && @user. avatar
old_avatar = User.find(params[:id]).avatar # 重新取user备用
end
if @user.update_attributes(params[:user])
old_avatar.remove! if old_avatar
end
redirect_to admin_groups_path
end
这样两次取@user,如果有更新,当保存成功时删除原有图片文件,否则不做处理。