ror “Paperclip”的插件处理图片

The product page for our application.

Paperclip 这个插件使我们给一个模型(model)添加一个附件变得非常容易。我们将给产品模型(Product model)添加一个字段(field),用来让每一个产品都能有一张产品图片。

Paperclip 的安装方法和其他插件的安装是一样的。在我们的rails项目目录中我们可以通过Github下载安装:

terminal
script/plugin install git://github.com/thoughtbot/paperclip.git

修改模型

到目前为止我们已经成功安装Paperclip插件,可以运行插件的生成器来给产品模型(Product model)添加附件字段。

terminal
script/generate paperclip products photo

这个生成器有两个参数。第一个是模型的名字,在例子中传入的是“Product”,第二个是新添加的附件字段的名字(photo)。这个生成器执行后会生成一个迁移任务(migration):给模型添加了4个新字段。

ruby
add_column :products, :photo_file_name, :string  
add_column :products, :photo_content_type, :string  
add_column :products, :photo_file_size, :integer  
add_column :products, :photo_updated_at, :datetime

Paperclip插件生成器添加的4个新字段 。

我们将运行命令:rake db:migrate 来更新数据库中的表products。

下一步 修改模型(model)代码。我们需要使用 has_attached_file 来告诉模型我们用迁移任务创建的附件字段(attachment field)的名字。

ruby
class Product < ActiveRecord::Base  
  belongs_to :category  
  has_attached_file :photo  
end

修改视图

创建和更新产品的表单需要添加一个上传文件的字段。

ruby
<% form_for @product, :html => { :multipart => true } do |form| %>  
  <ol class="formList">  
    <!-- Other fields go here... -->  
    <li>  
      <%= form.label :photo, "Photo" %>  
      <%= form.file_field :photo %>  
    <li>  
      <%= form.submit "Submit" %>  
    </li>  
  </ol>  
<% end %>

为表单添加了一个 file_field字段之后,还需要修改form_for来使表单能够接收文件附件,这是通过添加:multipart => true:html hash参数,这个参宿会给生成的form标签添加enctype="multipart/form-data"属性。

当然如果我们不去显示图片,那么我们上传图片是没有意义的,因此我们需要对显示产品的视图(show)进行修改。我们只需要给页面添加一个image_tag标签。我们的产品模型(Product model)已经有一个属性,这个属性是一个带有能够生成正确图片路径url方法的photo对象。调用代码如下。

ruby
<%= image_tag @product.photo.url %>

我们可以编辑一个产品,为之添加一个图片,然后看看结果。

The product's page now shows an image.

所做的修改生效了,我们的产品现在有一张图片显示了,但图片有点太大了。 当然我可以通过仅仅上传正确尺寸的图片来保证图片大小。如果我们可以在服务器上修改图片的尺寸,那么就能够很好的保证图片的尺寸了。Paperclip插件有方法可以做到。

设置图片尺寸

我们添加到产品模型(Product model)中的方法has_attached_file 有很多参数(options)。其中一个是允许我们给图片定义不同的尺寸的styles参数。我们只需要定义style参数并指定尺寸就可以为每张图片创建一个缩略图。例如:

ruby
has_attached_file :photo, :styles => { :small => "150x150>" }

添加了新的style之后 Paperclip将会给每张图片生成一张适应150×150象素尺寸的缩略图。 尺寸参数结尾的大于号告诉Paperclip要保持图片的纵横比,避免图片拉伸变形。要注意的是你必须在服务器上安装ImageMagick 来保证生成缩略图功能起作用。

为了让合适的尺寸的图片能够在产品视图(show)中显示,我们需要修改image_tag使图片标签的url指向小版本图片。

ruby
<%= image_tag @product.photo.url(:small) %>

给url方法传递刚刚设置的style :small参数正确的小图片将被返回。只有当上传的时候才能生成图片,因此为了重新生成图片尺寸我们只能编辑我们的产品重新上传图片文件。只有这样做了, 指定大小的图片才显示在产品页面。

The product page now shows the image at the correct size.

设置 Paperclip 路径

Paperclip默认将附件保存在rails项目的public/system目录下。

terminal
<img alt="Phone_large" src="http://asciicasts.com/system/photos/1/small/phone_large.jpg?1238845838" />

Paperclip 会根据产品的 id 和模型中设置的style来自动创建保存附件的自有目录层次。大多数情况下默认的目录层次是比较合适的,但是如果我们想将图片存储到其他目录,那么我们可以改变默认的存储位置。

只要给方法 has_attached_file 传递两个参数url和path就可以把图片文件保存到其他位置。

ruby
has_attached_file :photo, :styles => { :small => "150x150>" },  
  :url => "/system/:attachment/:id/:style/:basename.:extension",  
  :path => ":rails_root/public/system/:attachment/:id/:style/:basename.:extension"

上面代码中的参数url和path是Paperclip使用的默认值。url指定了相对于public的路径位置,其中有附件字段的名字(attachment)、模型的id和style替换占位符(placeholders)。path参数值中也有相似的替换占位符。如果想要将图片存储到assets目录中,我们只要改变url和path的值。

ruby
has_attached_file :photo, :styles => { :small => "150x150>" },  
  :url => "/assets/products/:id/:style/:basename.:extension",  
  :path => ":rails_root/public/assets/products/:id/:style/:basename.:extension"

现在我们上传的任何图片将会保存到assets目录目录而不是system/photos目录。

验证附件

Paperclip插件的最后一个重要特性是它可以验证我们上传的附件。可以通过给产品模型(Product model)添加类似下面的校验器:

ruby
validates_attachment_presence :photo  
validates_attachment_size :photo, :less_than => 5.megabytes  
validates_attachment_content_type :photo, :content_type => ['image/jpeg', 'image/png']

通过上面的这些校验方法检查了:附件是否上传、文件大小小于5m、是否为JPEG或PNG格式。用这种办法验证附件可以和验证其他字段一样。有一点要注意的是:检查的文件类型的时候 Internet Explorer 可能与其他浏览器报告不同的MIME类型:IE会认为JPEG文件是image/pjpeg而不是image/jpeg文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值