上传文件plugin:upload_column 比 file_column强得多!

本文详细介绍了UploadColumn插件的功能特点,包括自定义错误消息、图片处理接口、文件名定制等,并对比了与file_column的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

优于file_column是显而易见的。

本人发现的几处:

1、验证出错时,upload_column提供了自定义错误消息接口。file_column的消息是固定英文的,虽说可以改其源文件,但直接改plugin总是别扭些,也影响update。

2、upload_column提供了更全面的图片处理接口。不仅可以选择处理器,而且对于图片的处理也提供了单独调用处理器的方式。

  如:使用file_column时,我们在对图片进行缩放时,只能使用其提供的简单缩放模式,如果想调用magick对图片实现更多效果的图片处理,就没有这种接口了。

  而使用upload_column就不一样了,可以随意的调用图片处理器来对图片进行处理。

 

  upload_column :uploaded_data, :versions => [ :thumb ], :store_dir => proc{|record, file| "attachment/#{record.id}"}

  def uploaded_data_after_assign
    uploaded_data.thumb.process! do |img|
      img.resize_to_fill(200, 150) # javaeye的图片缩放就是用的resize_to_fill方式
    end
  end

 3、file_column的验证有问题。当对图片进行了缩放后,validates_filesize_of竟然是对缩放后的原图进行文件大小进行判断,而实际上我想要的是对原文件大小进行判断。

4、upload_column提供了文件名接口,可以把文件名改为自己所需要的名称。如可以使用uuid生成文件名。

  uuid_filename = UUID.new.generate
  upload_column :logo, :filename => proc{|inst, orig, ext| "#{uuid_filename}.#{ext}"}, :versions => [ :thumb ]

 5、upload_column的versions接口真棒。不再象file_column那样固定几个图片处理模式。upload_column可以任意定义自己的特别处理模式。只要加几个版本名,然后写个回调,就可以随心所欲的把图片处理成各种自定义的版本。

6、upload_column生成的版本文件名的样式是:XXXXX-version.ext,如4fe2e341-3bce-012c-5908-0016d32d937e-thumb.jpg,而不是象file_column会生成thumb这样的版本文件夹。

 

以上六个优点足以让我选择upload_column,而放弃file_column。

 

upload_column下载及说明:http://github.com/toy/upload_column/tree/master

 

下文再转载网上一篇翻译自upload_column的readme的文章。

原文地址:http://viviworld.blogbus.com/logs/28505967.html

作者:张伟

写道
UploadColumn - [翻译]
Tag:翻译
张伟点评:
这是UploadColumn 插件自带的README,我看了N遍,总是发现上次会遗漏某些东东。老外讲个东西,向来不是按照一二三四、常常泛泛而谈,看他们写的书,更是这样!中国人习惯了例子。
----------------------------------------------------
= UploadColumn

UploadColumn 是专为Ruby on Rails 框架打造的插件,支持上传文件、特别是图片。
假如你有一个用户列表,想给每个人关联一个图片。你应该把图片上传到数据库,或者借助 UploadColumn 在文件系统中实现简单存储。
如果一个名为 User 的 model 有一列'picture',类型为String,你只需在该 model 增加:

class User < ActiveRecord::Base
upload_column :picture
end

好了!你可以试着上传文件啦。当然, UploadColumn 有很多不同选项,供你自定义上传方式。
没有用户接口的文件上传可不好玩,做出如下设置:
在表单里增加一个 upload_column_field ,比如:

<p><label for="user_picture">Picture</label><br/>
<%= upload_column_field 'user', 'picture' %></p>
你应该用 upload_column_field 代替Rails的 file_field,以便在诸如验证失败导致表单重新呈现时,它仍然管用。不幸的是,file_field 不支持上述情形。

现在还有一点问题,由于它发送的是文件而非字符串。大可不必担心,如果我们设置表单的 encoding 为 multipart ,它就OK了。UploadColumn 甚至提供了一些好的 helper 来回避丑陋的 multipart 语法。形如:

<%= upload_form_tag( :action => 'create' ) %>

好了!你的上传已经做好了(但愿如此),你现在应该能够给用户增加图片了。疯狂的地方当然还在后面!

==存储路径

你并不想总是把图片存储在 upload_column 默认的路径,这不是问题,改变目录简直不值得一提。你给 upload_column 传一个 :store_dir 键,就会覆写默认机制,而启用该目录。

upload_column :picture, :store_dir => "pictures"

这完全符合当前情景。注意,所有文件将被存放于相同的目录。

如果需要对路径进行修改(或许按照关联id存储),请用 proc 。proc看起来如下所示:

upload_column :picture, :store_dir => proc{|record, file| "images/#{record.category.name}/#{record.id}/#{file.extension}"}

proc 被传给两个参数,第一个是模型类的当前实例,第二个是属性名称(这里,attr指 :picture)。

同样,你也可以修改 :tmp_dir 。

== 文件名

UploadColumn 默认将保留文件原始名称,有时显得不太方便。你可以给 upload_column 声明传递一个 :filename 指令:

upload_column :picture, :filename => "donkey.png"

这样所有文件将被命名为 donkey.png。如果文件是jpeg格式的就不是我们所期望的了。通常传一个Proc 给 :filename 比较明智。

upload_column :picture, :filename => proc{|record, file| "avatar#{record.id}.#{file.extension}"}

该 Proc 被传两个参数,当前实例和文件本身。

== Manipulators

UploadColumn 允许你通过 manipulators 操作文件,按某种格式转换文件,或实现任何种类的操作。目前绑定了两个 manipulators, RMagick manipulator 和 ImageScience manipulator,不过,自己写也很容易。网站上有进一步的说明。

== 用 RMagick 操作图片

比如你想(无论什么原因)让用户图片有一个时髦的曝光效果。upload_column 操作图片既可以在运行时、也可以在图片保存之后进行,有如下可能:

class User < ActiveRecord::Base
upload_column :picture, :manipulator => UploadColumn::Manipulators::RMagick

def picture_after_assign

picture.process! do |img|
img.solarize
end

end
end
你也能使用 :process 指令,当一个新图片被上传后,它会自动执行操作。如果你想把图片缩放到最大值为 800 * 600 的规格,可以这样做:

class User < ActiveRecord::Base
upload_column :picture, :process => '800x600', :manipulator => UploadColumn::Manipulators::RMagick
end

先前曝光的例子可以简写为:

class User < ActiveRecord::Base
upload_column :picture, :process => proc{|img| img.solarize }, :manipulator => UploadColumn::Manipulators::RMagick
end

或者我们想要图片的不同版本,就这样指定:

class User < ActiveRecord::Base
upload_column :picture, :versions => [ :solarized, :sepiatoned ], :manipulator => UploadColumn::Manipulators::RMagick

def picture_after_assign
picture.solarized.process! do |img|
img.solarize
end
picture.sepiatoned.process! do |img|
img.sepiatone
end
end
end

也可以为版本指定hash ,并传一个 dimension 或 proc:

class User < ActiveRecord::Base
upload_column :picture, :versions => { :thumb => "c100x100", :large => "200x300", :sepiatoned => proc{ |img| img.sepiatone } }, :manipulator => UploadColumn::Manipulators::RMagick
end

注意,thumb 的尺寸前的‘c’,它将把图片裁剪到精确尺寸。虽然有点啰嗦,它并不会检查文件到底是不是图片。曝光最新的 GreenDay 歌曲多少有些不太好听。鉴于此,UploadColumn 提供了 image_column 函数:

class User < ActiveRecord::Base
image_column :picture, :versions => { :thumb => "c100x100", :large => "200x300", :sepiatoned => proc{ |img| img.sepiatone } }
end

这也把图片放在了 public/images 而不是 public,多么整洁!

== 运行时渲染

你能在运行时操作图片(它非常耗性能)。在你的 controller 增加一个 action ,使用 UploadColumnRenderHelper.render_image.

def sepiatone
@user = User.find(parms[:id])
render_image @user.picture do |img|
img.sepiatone
end
end

就好了!

在 view 层,UploadColumnHelper.image 很容易为你的 action 产生一个 image 标签:

<%= image :action => "sepiatone", :id => 5 %>

== Views

如果上传文件是图片,那么你很可能想在 view 层显示出来,如果它是另一种文件,你将会做个超链接。借助 UploadColumn::BaseUploadedFile.url 会非常容易实现。

<%= link_to "Guitar Tablature", @song.tab.url %>

<%= image_tag @user.picture.url %>

== 魔术列

UploadColumn 允许你为 model 增加 'magic' 列,它将被合适数据自动填充。仅仅通过 migration 增加该列,例如:

add_column :users, :picture_content_type

如果我们的 model 为:

class User < ActiveRecord::Base
upload_column :picture
end

列 picture_content_type 将自动填充为文件的 content-type(至少是 UploadColumn 做的最好猜测)。

你能够使用 UploadColumn::UploadedFile 的任何方法,比如 size,url,store_dir 等等。

也可使用 picture_exif_date_time 或 picture_exif_model 等。当然,它仅仅适用于一个 JPEG 图片------唯一拥有 exif 数据的文件类型。这需要 EXIFR 类库,通过 gem 来安装:gem install exifr。

== 验证

UploadColumn 有它自己的验证方法,validates_integrity_of 。该方法将确保仅符合白名单上扩展名的文件才会被上传。这会阻止黑客上传可执行文件(像 .rb,.pl 或 .cgi 等)或限制某种文件允许被上传,例如仅限于图片。你能够用 :extensions 参数自定义白名单。

如果你仅仅允许 XHTML 和 XML 文件,你可以借助 XSLT 来控制:

upload_column :xml, :extensions => %w(xml html htm), :manipulator => MyXSLTProcessor

validates_integrity_of :xml

还可以在 UploadColumn 中使用一些 Rails 验证器。

validates_presence_of 和 validates_size_of 被证实管用。

validates_size_of :image, :maximum => 200000, :message => "is too big, must be smaller than 200kB!"

切记修改错误信息,UploadColumn 默认的看起来有点傻。

validates_uniqueness_of 不管用,这是由于 validates_uniqueness_of 发送(你的上传列)而不是请求实例变量,这样它会得到一个 UploadFile 对象,该对象不是真的和数据库中的其他值比较,不扰乱 Rails 内部机制而正常使用的确有点困难(如果你搞定了,请告诉我呀)。同时,你可以

validates_each :your_upload_column do |record, attr, value|
record.errors.add attr, 'already exists!' if YourModel.find( :first, :conditions => ["#{attr.to_s} = ?", value ] )
end

我知道,这不太优雅,但应该能用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值