相关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的项目配置文件中
如:
ServerName eva DocumentRoot /Users/P.Luo/vhosts/eva/public SetEnv RootEnv eva RailsEnv development RackEnv development SetEnv PATH /usr/bin:/usr/local/bin AllowOverride all Options -MultiViews Allow from all
参考: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| %><%= f.label :nickname %>
<%= f.text_field :nickname %><%= f.label :avatar %>
<%= image_tag(@user.avatar_url(:thumb)) if @user.avatar? %> <%= f.file_field :avatar %> <%= f.hidden_field :avatar_cache %><%= f.label :remove_avatar %>
<%= f.check_box :remove_avatar %> Remove Avatar<%= f.submit %><% 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,如果有更新,当保存成功时删除原有图片文件,否则不做处理。