Rails Paperclip interpolates and before_save with custom id - ruby-on-rails

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)

Related

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?

uninitialized constant Paperclip::Cropper

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.

how do sizing image with paperclip gem

i want to use avatar through paperclip. in tutorial use gravatar
messages_helper.rb
def recipients_options(chosen_recipient = nil)
s = ''
User.all.each do |user|
s << "<option value='#{user.id}'
data-img-src='#{gravatar_image_url(user.email, size: 50)}'
#{'selected' if user == chosen_recipient}>
#{user.name}</option>"
end
s.html_safe
end
i change on this code and it working.
module MessagesHelper
def recipients_options(chosen_recipient = nil)
s = ''
User.all.each do |user|
s << "<option value='#{user.id}' data-img-src='#{user.avatar.url(:thumb)}'
#{'selected' if user == chosen_recipient}>#{user.username}</option>"
end
s.html_safe
end
end
new.html.erb
<div class="form-group">
<%= label_tag 'recipients', 'Choose recipients' %>
<%= select_tag 'recipients', recipients_options(#chosen_recipient), multiple: true, class: 'form-control chosen-it ' %>
</div>
user.rb
has_attached_file :avatar, :styles => { :medium => "150x150>", :thumb => "30x30#" }, default_url: "https://s3.amazonaws.com/myinstick/logo/instagram-icon.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
But! if user dont have avatar, that use image paperclip default. and it does not scaling and It looks big. how to set the style or size.
it looks like this
in your model:
has_attached_file :avatar,
:styles => { thumb: "100x100#", medium: "300x300#", large: "900x500#"}
or whatever size you want it to be. The # is for cropping. It will select the center of the image and crop the specified height and width from there. You can also just use the default > if you don't want the cropping... and in your view:
<%= image_tag #user.avatar.url(:medium) %>
I solved the problem. Drop-down list uses
jquery.image-select.js
(function($) {
// Image template, this can be overridden from the constructor (options.template),
// must contains {src} placeholder. Ther eare two class names 'chose-image' or 'chose-image-small', modifiy in CSS
var fn_template = '<img class="{class_name} " src="{url}" />';
// Store the original 'chosen' method
var fn_chosen = $.fn.chosen;........
I can set class for all images, like this
var fn_template = '<img class="{class_name} image-circle-minisize" src="{url}" />';
and everything works

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

Paperclip override validates_attachment in subclass

I am trying to override validates_attachment in Subclass but I notice it only works well with Superclass validation; I wonder why my validates_attachment in subclass doesn't work. Has anybody faced this problem? and how have you solved this problem? Here is an example code:
class Superclass
validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "28", "4:1" => "50", "5:1" => "40"} }
end
class Subclass < Superclass
validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "40", "2:1" => "60"} }
end
I suggest that you should put both the class's fields in different tables. It could be possible that you are getting problems because of that.
However if you really want to have only one table for both the classes then I believe that you could use something like this:
validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "40", "2:1" => "60"} }, :unless => Proc.new {|attach| attach.type == "SubClass"}
I assumed that you have a attach_type column but depending on how you are determining whether the attachment type is a SubClass, it is left upto you to change it.
You could also try to remove your validates_attachment from the Subclass and instead try with_options in your model, like the following:
with_options :unless => :attach_type == "SubClass" do |attach|
attach.validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "40", "2:1" => "60"}}
end
This works for me... rails 4
validates :photo, :presence => true,
:attachment_content_type => { :content_type => "image/jpg" },
:attachment_size => { :in => 0..10.kilobytes }
Incase anyone else runs into an issue where they need instance access before they can validate I used the following:
class AttachmentDynamicContentTypeValidator < Paperclip::Validators::AttachmentContentTypeValidator
def validate_each(record, attribute, value)
#record = record
super
end
def allowed_types
#record.my_valid_types_array || ["text/plain"]
end
def check_validity!; end
end
And in the actual asset instance I added the following:
class Asset < ActiveRecord::Base
validates :asset, attachment_dynamic_content_type: :asset_content_type
end
Hope that helps someone.

Resources