Module: Cropper::ClassMethods
- Defined in:
- lib/cropper.rb
Overview
Cropper::ClassMethods is included into ActiveRecord::Base in the same way as the Paperclip module. It adds a ‘has_upload` class method that defines an attachment and adds several instance methods that will return the values that determine its cropping. Those values are usually but not
necessarily given by the user.
Instance Method Summary collapse
-
#has_upload(attachment_name = :image, options = {}) ⇒ Object
Defining upload columns.
Instance Method Details
#has_upload(attachment_name = :image, options = {}) ⇒ Object
Defining upload columns
has_upload brings in the whole machinery of receiving and cropping an uploaded file. The options given are exactly the same as paperclip’s ‘has_attached_file` call, with the addition of a ’crop’ parameter that gives the target dimensions. The crop value is applied in the upload object, then any other styles you specify here are applied to that cropped image when it is passed to this model.
The practical effect of this is that your :original file always has your :crop dimensions.
You can also set an optional :precrop option to set the dimensions of the file that is presented in the cropping interface. The default is 1600x1600<, which is often going to be too big and may cause unwanted scaling-up of your source image. The precrop geometry is also applied in the upload object, when a file is first uploaded.
The call usually looks like this:
class User < ActiveRecord::Base
has_upload :avatar,
:precrop => '1440x960<
:crop => '720x480#'
:styles => {
:thumbnail => "60x60#"
}
The crop geometry will always be treated as a fixed target shape: that is, as though it ended in ‘#’. Any other suffix will be removed. The other styles that you define can be in any form that paperclip understands.
A model can make more than one has_upload call. The methods we define here are all prefixed with the association name, so you usually end up calling methods like ‘person.icon_upload`.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/cropper.rb', line 84 def has_upload(=:image, ={}) # unless !table_exists? || column_names.include?("#{attachment_name}_upload_id") # raise RuntimeError, "has_upload(#{attachment_name}) called on class #{self.to_s} but we have no #{attachment_name}_upload_id column" unless # end # allow uploads to be assigned to this class and column in the UploadsController. .reverse_merge!(:geometry => "960x640#", :whiny => true, :styles => {}) [:styles].reverse_merge!({:precrop => "1600x1600<"}) Cropper.declare_uploadable(self, , ) ### Upload association # # [uploads](/app/models/upload.html) are the original image files uploaded and cropped by this person. # has_many :uploads, :class_name => "Cropper::Upload", :as => :holder # so what happens when we call this twice? # Ok, I give in. We have to require an image_upload_id column. It's silly trying to fake the whole association machine. belongs_to :"#{}_upload", :class_name => "Cropper::Upload", :autosave => true # accepts_nested_attributes_for :"#{attachment_name}_upload" attr_accessible :"#{}_upload_attributes" after_save :"connect_to_#{}_upload" #...but we still need to intervene to set the holder_column column of the upload when it is assigned define_method :"#{}_upload_with_holder_column=" do |upload| upload.holder_column = send :"#{}_upload_without_holder_column=", upload end alias_method_chain :"#{}_upload=", :holder_column #...or built. define_method :"build_#{}_upload_with_holder_column" do |attributes={}, ={}| attributes[:holder_column] = attributes[:holder_type] ||= self.class.to_s unless attributes[:holder] send :"build_#{}_upload_without_holder_column", attributes, end alias_method_chain :"build_#{}_upload", :holder_column # when a new holder is created, the interface means that the upload will have preceded it. In that # case we will have forced the setting of holder_type to allow crop-dimension lookups. When eventually # saving, we have to make sure that holder_id is also present. define_method :"connect_to_#{}_upload" do if upload = send(:"#{}_upload") upload.update_column(:holder_type, self.class.to_s) upload.update_column(:holder_id, self.id) upload.update_column(:holder_column, ) end Rails.logger.warn "connect_to_#{}_upload: upload is #{upload.inspect}. Self is #{self.inspect}" true end define_method :"#{}_upload_attributes=" do |attributes| # assign_nested_attributes_for_image_upload_association(:image_upload, attributes, mass_assignment_options) if upload_id = attributes.delete('id') self.send :"#{}_upload=", Cropper::Upload.find(upload_id) end if upload = self.send(:"#{}_upload") Rails.logger.warn "setting upload attributes for #{upload.inspect} -> #{attributes.inspect}" upload.assign_attributes(attributes) end end ### Attachment # # Eventually we get to the point. Image attachments work in the usual Paperclip way except that they are always received from # an upload object, presumably in an already-cropped form. # If this class then generates other styles, they are built from that cropped image rather than the file originally uploaded. # has_attached_file , # Note: updates to the attached file are pushed to the holder from the upload after processing is complete, so we won't always # have them immediately. Best course is to display the upload cropped rather than the holder original. end |