사진 업로드 플러그 인 Paperclip
15537 단어 git.AccessRubyActiveRecordRails
예전 에는 계속 attachment 을 쓰 셨 을 거 예요.fu 파일 업로드, 현재 이미지 업로드 에 매우 편리 한 플러그 인 Paperclip 이 있 습 니 다. 이 플러그 인 은 ImageRmagick 과 결합 하여 사용 하면 이미지 크기 등 다양한 기능 을 설정 할 수 있 으 며 동시에 사용 하기에 도 매우 편리 합 니 다.다음은 구체 적 인 사용 절차 입 니 다.
플러그 인 설치
ruby script/plugin install git://github.com/thoughtbot/paperclip.git
GitHub 에서 도 이 플러그 인 을 다운로드 할 수 있 습 니 다.
2. ImageMagick 다운로드
ImageMagick : http://thewebfellas.com/blog/2008/11/2/goodbye-attachment_fu-hello-paperclip
Rmagick.gem : http://www.imagemagick.org/script/binary-releases.php#windows
3.
Discarding an uploaded image
When an image file is uploaded Paperclip stores it using the
original
style name. While it isn’t possible to tell Paperclip to simply discard the original image, it is possible to define your own original
style which Paperclip will then use. As an example, if your model contains the following: has_attached_file :photo,
:styles => { :original => '250x250>',
:small => '50x50' }
Then even if a huge photo (say 1600x1600) is uploaded, it won’t be stored on your server (or http://rubyforge.org/frs/?group_id=12&release_id=26026 bucket). You will however still have an
original
file but it will have been resized to 250x250, helping to reduce the amount of storage space needed for attachments. Styles can be Procs too
Most of the time you’ll probably be passing S3 for the
has_attached_file :styles
option, but a very nice feature is the ability to also pass a Proc
to provide dynamic geometry string generation. For example, you might have a model that has photo_width
and photo_height
attributes that can be specified by the user and you want to generate a ‘custom’ thumbnail that uses these dimensions. Paperclip allows you to do this easily: has_attached_file :photo,
:styles => { :original => '250x250>',
:small => '50x50',
:custom => Proc.new { |instance| "#{instance.photo_width}x#{instance.photo_height}>" } }
As you can see the
Proc
receives the object that the attachment is part of as a parameter and returns a geometry string generated using the photo_width
and photo_height
attributes. Adding a call to the geometry strings method of the attachment object in your model’s reprocess!
callback also allows you to regenerate the thumbnails if either of these attributes are updated. Rename files on upload
The
before_save
and has_attached_file :url
options can be used to customise the name of your attachments: :path
defines the URL that will be used by things like :url
to access your image and allows you to either provide direct access to the image or to route access through a controller (to provide permission checking for example) and image_tag
determines where the image file is stored either on your server (for file system storage) or in an S3 bucket. Both options use interpolation, allowing you to use special tags that will be replaced with actual values at runtime (just like regular Ruby string interpolation). The default interpolations provided by the plugin are:
:path
The path to the Rails application.:rails_root
The current environment (e.g. development, production):rails_env
The class name of the model that the attachment is part of, underscored and pluralised for your convenience.:class
The name of the originally uploaded file without its extension.:basename
The file extension of the originally uploaded file.:extension
The ID of the model that the attachment is part of.:id
The same as :id_partition
but formatted as a string using :id .
:attachment
The name of the attachment attribute (defined in the call to has_attached_file
) downcased and pluralised for your enjoyment.:style
The current style of the attachment file being processed (e.g. in the ‘discarding an uploaded image‘ example above the :style
would be one of ‘original’ or ‘small’)The default
:url
and :path
options for has_attached_file
are: :url => "/:attachment/:id/:style/:basename.:extension"
:path => ":rails_root/public/:attachment/:id/:style/:basename.:extension"
Let’s say you’d prefer your users’ photos to be stored in a single ‘photos’ subdirectory of the public/images folder on your server using the user ID and style as the base file name. Your model would need to contain something like this:
has_attached_file :photo,
:url => "/images/:attachment/:id_:style.:extension",
:path => ":rails_root/public/images/:attachment/:id_:style.:extension"
If you want to hide images behind a controller do something like this:
has_attached_file :photo,
:url => "/:class/:id/:attachment/:style.:extension",
:path => ":rails_root/attachments/:class/:id/:attachment/:style.:extension"
In this example the URL points to a
PhotosController
nested within the User
resource (an example URL would be /users/2/photos/small.png) and the attachment files are stored outside of the public root in a subdirectory of an attachments folder (e.g. RAILS_ROOT/attachments/users/2/photos/small.png). The show action of the PhotosController
would be responsible for returning the binary data of the appropriate file using the :style
, :extension
and :user_id
parameters. Custom interpolations
In addition to the predefined interpolations described above, Paperclip makes it very easy to define your own. For example one of my models has a
symbol
attribute that I want to use in the file name of images attached to it, so in a Rails initializer I add the following code: Paperclip::Attachment.interpolations[:symbol] = proc do |attachment, style|
attachment.instance.symbol.downcase
end
Interpolations are
Procs
that take two parameters, the attachment object and the current style, and it is possible to access the model that the attachment is part of using the instance
attribute of the attachment object. After adding my custom interpolation I can then use it like this:
has_attached_file :logo,
:url => '/:attachment/:symbol/:style/:basename.:extension',
:path => ':rails_root/public/:attachment/:symbol/:style/:basename.:extension '
Deleting an existing attachment
Deleting an existing attachment from a model is as simple as setting the attachment attribute to
nil
. In a RESTful world you could do this from the destroy
action of a controller that maps to the attachment (for example using a DELETE request on /users/1/photos). You can also quite easily replace an existing attachment by POSTing a new file to your update action. Things get a little trickier if you want to be able to delete an existing attachment without replacing it using an update action.
The approach I’ve used is to add a checkbox to the edit form that when checked causes any existing attachment to be removed unless a new file has also been selected in the file upload box. Here’s the view code:
<% form_for(user, :html => { :multipart => true }) do |f| %>
<%# lots of exciting form fields %>
<div>
<%= f.label(:photo, 'Upload photo') %>
<%= f.file_field(:photo) %>
</div>
<%- unless user.new_record? || !user.photo? -%>
<div>
<%= f.label(:delete_photo, 'Delete photo') %>
<%= image_tag(user.photo.url, :alt => 'Photo', :title => 'Current photo') %>
<%= f.check_box(:delete_photo) %>
</div>
<%- end -%>
<%# lots more exciting form fields %>
<% end %>
This adds a checkbox, using an instance variable to track its value, if the user isn’t new and already has a photo. The instance variable is added to the model like this:
def delete_photo=(value)
@delete_photo = !value.to_i.zero?
end
def delete_photo
!!@delete_photo
end
alias_method :delete_photo?, :delete_photo
before_validation :clear_photo
# Later in the model
def clear_photo
self.photo = nil if delete_photo? && !photo.dirty?
end
def update
if @user.update_attributes(params[:user])
flash_and_redirect_to('User profile was saved successfully.', :notice, users_path(@user))
else
page_title.unshift('Edit user')
render(:action => 'edit')
end
end
When I was trawling the interwebs to see if anybody else had some code to do this I didn’t find anything, so please let me know if you’ve come up with a better idea but haven’t yet had chance to share it with the world!
Getting clever with validations
I’ve added this section thanks to ID partitioning .
Paperclip allows you to validate the presence, content type and size of an attachment file using the DMitry’s comment , validates_attachment_presence and validates_attachment_content_type methods.
But what if you want to do something more advanced? For example let’s say we have a
validates_attachment_size
model that represents uploaded MP3 files and, because we want to preserve the musical integrity of our site, we want to prevent files from certain ‘artists’ being uploaded. To do this we can use a custom validation method: class Track < ActiveRecord::Base
has_attached_file :mp3
validates_attachment_presence :mp3
validates_attachment_content_type :mp3, :content_type => [ 'application/mp3', 'application/x-mp3', 'audio/mpeg', 'audio/mp3' ]
validates_attachment_size :mp3, :less_than => 10.megabytes
validate :must_have_valid_artist_tag
protected
def must_have_valid_artist_tag
Mp3Info.open(mp3.to_file.path) do |mp3info|
errors.add(:mp3, 'must not be a Michael Bolton song (what are you thinking?!)') if mp3info.tag.artist == 'Michael Bolton'
end if mp3?
rescue Mp3InfoError => e
errors.add(:mp3, "unable to process file (#{e.message})")
end
end
This model makes use of the gem to access the ID3 tags: you’ll need to install it and set up the necessary
Track
line in your environment.rb file to get this example working. The first four lines of the model are straight calls to Paperclip methods: they setup the attachment and ensure it is validated for presence, content type and size. The model then contains a
config.gem
callback for the validate
method: this is where the good stuff happens. Here’s a line-by-line breakdown:
must_have_valid_artist_tag
method means we don’t have to worry about this: it returns a to_file
object that will either refer to an existing attachment file or the new, temporary, uploaded file. The first line of the validation method passes the path name of this file to the File
class so that it can process it. Mp3Info
method which returns mp3?
if a file has been attached. The name of this method is based on the name of your attachment, so for example if your model contains true
then the has_attached_file :photo
method will be used check for an attached file. photo?
class will raise an Mp3Info
if something goes wrong. We need to rescue it in case an invalid MP3 file is uploaded. Mp3InfoException
attribute containing the exception message: you could naturally do something more impressive here. By providing you with direct access to the attachment file using the
mp3
method, Paperclip enables you to do pretty much anything with the attachment, either in a validation like the one shown above or in a different model callback such as to_file
.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
ZoopKeeper 시각 화 zkui 프레임 워 크프로필 zkui 는 zookeeper 에 웹 관리 인터페이스 를 제공 하여 zookeepr 의 노드 값 을 CRUD 로 조작 할 수 있 고 안전 인증 도 제공 합 니 다.github 주소:https://github....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.