uninitialized constant Paperclip::Cropper - ruby-on-rails

I have a custom processor for my Paperclip styles: cropper.rb. Though it is not called and return NameError (uninitialized constant Paperclip::Cropper) error.
It has been discussed here : Rails3 and Paperclip but a while ago. It was concerning Rails 3 back then.
I am under Rails 5 (update from Rails 4.x)
Profilepic.rb
class Profilepic < ApplicationRecord
belongs_to :professionnels
has_attached_file :image, styles: { big: "1200x1200", medium: "400x400", small: "250x250"}
validates_attachment :image, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }, size: {less_than: 10.megabytes}
has_attached_file :finalimage, styles: { medium: "500x500", small: "200x200"}, whiny: false, use_timestamp: false, processors: [:cropper]
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
end
lib/paperclip_processors/cropper.rb
module Paperclip
class CustomCropper < Thumbnail
def initialize(file, options = {}, attachment = nil)
super
if target.crop_w && target.crop_x
#current_geometry.width = target.crop_w
#current_geometry.height = target.crop_h
end
end
def target
#attachment.instance
end
def transformation_command
# call crop processing only if user inputs are there
if target.crop_w && target.crop_x
crop_command = [
"-crop",
"#{target.crop_w}x" \
"#{target.crop_h}+" \
"#{target.crop_x}+" \
"#{target.crop_y}",
"+repage"
]
crop_command + super
else
super
end
end
end
end

OK spent a day to realize the correct lib subfolder is actually paperclip and not paperclip_processors although Paperclip Git does mention both as valid and automatically loaded.

Related

Rails Paperclip interpolates and before_save with custom id

In my app (Rails 5.2), my model uses an id with UUID type .
I have created one more field: id_server which will be the id I want to use with paperclip for :id_partition to create multiple folders (default id_partition works with id field, not with another field).
I have done that:
before_save do
id_server = Photo.maximum(:id_server) + 1
end
to create the next id_server.
And for Paperclip:
# paperclip
has_attached_file :file, path: "/upload/:class/:attachment/:id_server_partition/:style/:basename.:extension",
styles: { :tiny => "140x140>", :small => "160x240", :high => "640x960" }
validates_attachment :file, content_type: { content_type: ['image/jpg', 'image/jpeg', 'image/pjpeg', 'image/png', 'image/x-png'] }
validates_attachment :file, size: { in: 0..5.megabytes }
# create multiple folders path with id_server
Paperclip.interpolates :id_server_partition do |attachment, style|
attachment.instance.id_server_partition
end
def id_server_partition
("%09d".freeze % id_server).scan(/\d{3}/).join("/".freeze)
end
The fact is before_save() seems to never be called before Paperclip.interpolates.
id_server is nil in:
("%09d".freeze % id_server).scan(/\d{3}/).join("/".freeze)
can't convert nil into Integer
What did I miss ?
Strangely, it was because self was missing in:
before_save do
end
so this works, and the id_server is created here:
self.id_server = Photo.maximum(:id_server) + 1
but not this:
id_server = Photo.maximum(:id_server) + 1
But here, no need of the self before id_server:
("%09d".freeze % id_server).scan(/\d{3}/).join("/".freeze)

paperclip resize not working for dynamic columns on attachment model

I have a two columns on my attachment model on which the user sets the dimension to which they want to resize the image.
However, the variables when the resize happens are nil, but set to actual values after the resize happens.
below is the code
has_attached_file :file, :styles => lambda { |a|
{ :logo => ["200x50>",:png],
:user_defined => ["#{a.instance.custom_width}x#{a.instance.custom_height}>",:png] }
}
the custom_width & custom_height are nil when conversion happens however the logo conversion works as expected.
I am using ruby 2.2.4p230 & Rails 4.2.4
below is the full mode code
class Attachment < ActiveRecord::Base
belongs_to :model_one
belongs_to :attachable, polymorphic: true
#has_attached_file :file, styles: { logo: ['200x50>',:png] }
has_attached_file :file, styles: lambda { |attachment| attachment.instance.styles }
def styles
Rails.logger.info self.inspect
Rails.logger.info self.attachable
styles = {}
m = "200x50>"
l = "#{self.custom_width}x#{self.custom_height}>"
styles[:logo] = [m, :png]
styles[:user_defined] = [l, :png]
styles
end
end
Can anyone please help and let me know if i am doing something wrong?

Rails set new dimentions image paperclip

Is there any way to set new dimensions to my_image and save it to AWS S3?
I have
my_image = Post.last.photo.image
geometry = Paperclip::Geometry.from_file(my_image.url)
so i want to set new geometry and save it
geometry = 'my params'
my_image.save
Of course i have my
has_attached_file :image, :styles => { :large => "220x" ..other styles}
My main goal set new dimensions during cropping photo with Jcrop
so when i receive new params like my_params=>"crop_x"=>"83", "crop_y"=>"24", "crop_w"=>"76", "crop_h"=>"76" set it as new style inside has_attached_file
You can do that easily,
Declare attribute accessors for the crop dimensions
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
Then you need to override the processor, create cropper.rb in /lib/paperclip_processors and add following code
module Paperclip
class Cropper < Thumbnail
def transformation_command
if crop_command
crop_command + super.join(' ').sub(/ -crop \S+/, '').split(' ') # super returns an array like this: ["-resize", "100x", "-crop", "100x100+0+0", "+repage"]
else
super
end
end
def crop_command
target = #attachment.instance
if target.cropping?
["-crop", "#{target.crop_w}x#{target.crop_h}+#{target.crop_x}+#{target.crop_y}"]
end
end
end
end
Now in the model you can do this
has_attached_file :image, styles: { large: "800X800>" }, default_url: "/images/:style/missing.png", :processors => [:cropper]
after_save :reprocess_image, if: :cropping?
def cropping?
!crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
end
def reprocess_image
image.assign(image)
image.save
end
Hope this helps!

How to upload image in a rails json api using paperclip?

Hi I'm building a json api on rails. I have a model class Product that has a image associated with it.
Here's my Products Controller
def create
params[:product][:image] = parse_image_data(params[:product][:image]) if params[:product][:image]
product = Product.new(product_params)
product.image = params[:product][:image]
if product.save
render json: product, status: 201
else
render json: {error: product.errors}, status: 422
end
end
private
def product_params
params.require(:product).permit(:title,:description,:published,:product_type, :user_id, :image, address_attributes:[:address, :city_id])
end
def parse_image_data(image_data)
#tempfile = Tempfile.new('item_image')
#tempfile.binmode
#tempfile.write Base64.decode64(image_data[:content])
#tempfile.rewind
uploaded_file = ActionDispatch::Http::UploadedFile.new(
tempfile: #tempfile,
filename: image_data[:filename]
)
uploaded_file.content_type = image_data[:content_type]
uploaded_file
end
def clean_tempfile
if #tempfile
#tempfile.close
#tempfile.unlink
end
end
The Product Model :
class Product < ActiveRecord::Base
belongs_to :user
has_one :address
has_attached_file :image, styles: { thumb: ["64x64#", :jpg],
original: ['500x500>', :jpg] },
convert_options: { thumb: "-quality 75 -strip",
original: "-quality 85 -strip" }
validates :title, :description, :user_id, presence: true
validates :product_type, numericality:{:greater_than => 0, :less_than_or_equal_to => 2}, presence: true
accepts_nested_attributes_for :address
validates_attachment :image,
content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] },
size: { in: 0..500.kilobytes }
end
I'm sending the post request using postman with the following request payload :
{
"product": {
"title":"Lumial 940",
"description": "A black coloured phone found in Hudda Metro Station",
"published": "true",
"product_type":"2",
"user_id":"1",
"address_attributes":{
"address": "Flat 16, Sharan Apartments, South City 1",
"city_id": "2"
},
"image":{
"filename": "minka.jpg",
"content": "BASE64 STRING",
"content_type": "image/jpeg"
}
}
}
But while creating, the Product is being created with the image properties but the image_path attribute is saved as null in the database. I can see the image being written in the public directory under my rails application. How can I get to save the image_path as well?
Can someone help me how to solve this?

How to Re-size Images that are Too Large on-the-fly with Paperclip and Rails 3

I am trying to implement the steps to check and resize images with paperclip based on this blog post: http://www.techdarkside.com/how-to-re-size-images-that-are-too-large-on-the-fly-with-paperclip-and-rails
Here is what I have in place...
class Question < ActiveRecord::Base
# subclasses
class Question::Image < Asset
has_attached_file :attachment,
:url => "/uploads/:class/:attachment/:id_partition/:basename_:style.:extension",
:styles => Proc.new { |attachment| attachment.instance.styles },
:styles => Proc.new { |attachment| attachment.instance.resize }
attr_accessible :attachment
# http://www.ryanalynporter.com/2012/06/07/resizing-thumbnails-on-demand-with-paperclip-and-rails/
def dynamic_style_format_symbol
URI.escape(#dynamic_style_format).to_sym
end
def styles
unless #dynamic_style_format.blank?
{ dynamic_style_format_symbol => #dynamic_style_format }
else
{ :medium => "300x300>", :thumb => "100x100>" }
end
end
def dynamic_attachment_url(format)
#dynamic_style_format = format
attachment.reprocess!(dynamic_style_format_symbol) unless attachment.exists?(dynamic_style_format_symbol)
attachment.url(dynamic_style_format_symbol)
end
def resize
if self.attachment_file_size > 2000000
"300x300>"
else
" "
end
end
end
I'm thinking the issue is with the reuse of the :styles symbol, however I'm not sure how to work both the styles method AND the resize method into a single Proc statement.
Here is what I ended up with thanks to #janfoeh suggestion. I did need to add :originalto the options in style to get this to work. I also bumped the max file size up to 5mb.
class Question < ActiveRecord::Base
# subclasses
class Question::Image < Asset
has_attached_file :attachment,
:url => "/uploads/:class/:attachment/:id_partition/:basename_:style.:extension",
:styles => Proc.new { |attachment| attachment.instance.styles }
attr_accessible :attachment
# http://www.ryanalynporter.com/2012/06/07/resizing-thumbnails-on-demand-with-paperclip-and-rails/
def dynamic_style_format_symbol
URI.escape(#dynamic_style_format).to_sym
end
def styles
unless #dynamic_style_format.blank?
{ dynamic_style_format_symbol => #dynamic_style_format }
else
{ :original => resize, :medium => "300x300>", :thumb => "100x100>" }
end
end
def dynamic_attachment_url(format)
#dynamic_style_format = format
attachment.reprocess!(dynamic_style_format_symbol) unless attachment.exists?(dynamic_style_format_symbol)
attachment.url(dynamic_style_format_symbol)
end
def resize
if self.attachment_file_size > 5000000
"1000x1000>"
else
" "
end
end
end

Resources