Adding Paperclip Attachment to Spree Orders Table, - ruby-on-rails

I am working on an ecommerce website using Solidus, Rails. The site allows you to order photo frames & prints from a variety of options.
To print a photo a user must upload the jpg file of the photo. So, to allow that I modified the orders table and added a paperclip attachment called 'attachment'
I ran the following command
rails generate paperclip SpreeOrder attachment
Which generated the migrations, then I ran rake db:migrate
Then I created a spree/order_decorator.rb file, and added has_attached_file
module Spree::OrderDecorator
has_attached_file :attachment, styles: {
:medium => {
:geometry => "640x480",
:format => 'jpeg'
},
:thumb => { :geometry => "160x120", :format => 'jpeg', :time => 10}
}, :processors => [:transcoder]
validates_attachment_content_type :attachment, content_type: /\Aimage\/.*\z/
Spree::Order.prepend self
end
After this I ran the server, and ended up getting this error
undefined method `has_attached_file' for Spree::OrderDecorator:Module (NoMethodError)
I have configured solidus for use with paperclip only, so I am really confused as to why I am getting this error, even later I manually went and generated a paperclip.rb file in the config/initializers directory, but still I get the same error.
Please help with this!!
Thank You!!

You should add those paperclip method at class level in the prepended module:
def self.prepended(base)
base.has_attached_file
end

Related

Paperclip validation issue on production

I have a Problem when I deploy my application on google cloud I get this error
has contents that are not what they are reported to be
Locally it works fine! I already tried to using the command_path. So I really don't know what I have to do next...
This is my model
has_mongoid_attached_file :image,
:styles => { :large => "380x380!" , :medium => "240x240", :small => "120x120!" },
:storage => :fog,
:fog_public => true,
:fog_directory => 'XXXX',
:path => "images/:id/:style/:basename.:extension",
:fog_credentials => { :provider => 'Google',
:google_storage_access_key_id => 'XXXXX',
:google_storage_secret_access_key => 'XXXXX'}
validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
Thank you for your efforts. I hope you guys can help me
Okay I found a result. I just created a initializers/paperclip.rb file
require 'paperclip/media_type_spoof_detector'
module Paperclip
class MediaTypeSpoofDetector
def spoofed?
false
end
end
end
Right now it work's perfectly for me.
If you have problems with ImageMagick on App Engine using Rails see this link
That issue occurs because the content-type discovered from file command returns empty string.
Actually system is not able to find the file executable so a exception is raised and empty string is returned back.
Check the code below
begin
Paperclip.run("file", "-b --mime :file", :file => '/tmp/RackMultipart20160826-15649-kwvnq2.png').split(/[:;]\s+/).first
rescue Cocaine::CommandLineError
""
end
Solution:-
Add below line in you initializer file.
Paperclip.options[:command_path] = '/usr/bin'
Looks like Google Cloud can't determine MIME type of uploaded files.
You can map file extensions to types in you initializer (application.rb, production.rb or create initializers/paperclip.rb)
Paperclip.options[:content_type_mappings] = {
:jpg => "image/jpeg",
:png => "image/png",
:gif => "image/gif"
}
But this way spoofing check won't be performed for image files.
I know I am late to the party, but in working with a legacy RoR system, I ran into this issue. The problem arose in setting the app up in Docker. Ultimately paperclip calling imagemagick was attempting to use file to identify mime-type and the minimal Docker did not have it installed. apt-get install file fixed it.

How does lambda function works in rails with an example from paperclip gem

I had a problem with the Paperclip gem where the default_url doesn't load after it fingerprinted in production environment, my code was like this:
class User
# Attachments to Paperclip - Profile pic
has_attached_file :profilepic_attachment,
:styles => {
thumb: '100x100#',
square: '500x500#'
},
:default_url => ActionController::Base.helpers.asset_path("missing/default_user.png"),
:preserve_files => true
validates_attachment_content_type :profilepic_attachment, content_type: /\Aimage\/.*\Z/
end
Note that when I do rails c in production and print out ActionController::Base.helpers.asset_path("missing/default_user.png"). The fingerprinted version (correct version) is printed out.
default_user-fb34158daae99f297ad672c43bb1a4d3917d8e272b5f2254aa055392aa2faa94.png.
However, when I inspect it from browser, the original /assets/missing/default_user.png appeared.
I struggled for long time until I came across this post, which tells me to change
:default_url => ActionController::Base.helpers.asset_path("missing/default_user.png"),
to
:default_url => lambda { |image| ActionController::Base.helpers.asset_path("missing/default_user.png") },
I wasn't sure what happened, but then it works. I then wonder what lambda function is for and when is it used in rails? also, it passed in a variable |image| but seems it wasn't use in the code. Why is that?
Thanks!

Paperclip security validation error mp4

I am using Paperclip to upload videos and keep getting a Security Validation error about the content type
The error when saving an mp4 to my model class is "content type discovered from file command: video/mp4. See documentation to allow this combination."
The save looks like this
AssignmentEventVideo.create(video: "https://s3-ap-southeast-2.amazonaws.com/dev/upload/0c857445-09ad-44b6-bbfa-810a9974a501/ScreenCaptureProject4.mp4")
The model class
class AssignmentEventVideo < ActiveRecord::Base
has_attached_file :video, :styles => {
:medium => { :geometry => "640x480", :format => 'mp4' },
:android => { :geometry => "640x480", :format => 'webm'},
:mobile => { :geometry => "300x300", :format => 'png', :time => 2 },
:thumb => { :geometry => "100x100#", :format => 'png', :time => 2 }
}
validates_attachment_content_type :video, content_type: ['video/mp4']
end
If have tried disabling validation all together with the code below but it still throws the error
do_not_validate_attachment_file_type :video
I have confirmed that the file command is return the correct type with
file -b --mime ScreenCaptureProject3.mp4
which returns
video/mp4; charset=binary
The save is working fine for another model class that accepts images and checks content using
validates_attachment_content_type :photo, content_type: /\Aimage\/.*\Z/
I'm not sure where to turn next - except to recreate the class and change the column name to something that doesn't clash with video?
Hope someone can help!
Thanks katafrakt - you got me on the right path.
I was using a presigned_post and uploading to S3 using JQuery FileUploader. This was not setting the Content-Type and I was getting back a binary/octet type that Paperclip didn't know how to deal with.
I set content_type on the presigned post, which stores the right meta data in S3 and all is well.

Paperclip attachment saving with incorrect S3 URL about 50% of the time

Update:
So this is definitely related to the :hash_data option, specifically the :updated_at segment. Somehow the files are being saved to the S3 bucket with a different :updated_at value than Paperclip uses to read the file. Could this be due to some race condition, considering that it occurs intermittently? As I mentioned below, this issue began after upgrading Paperclip to 4.2.1.
I will greatly appreciate any thoughts/tips you guys have on this. Thank you!
When uploading images via Paperclip to S3 bucket, it sometimes saves the files with a different filename than that returned by the attachment#url method. For example, an image is saved to
main_event_photos_46_47fd4f3c2fea17fbb7a0bd27c648911557f9e12b_main.png
However calling #event.main_event_photo.url(:main) returns
main_event_photos_46_15744de74a36207b672356b5ad4c6b30eb4ba85f_main.png
So as you can see, the :hash section of the interpolation does not match, and I have no way of finding the actual url besides opening the bucket in the S3 console. This issue seems to occur about half the time. Sometimes uploading the exact same file does save properly, and the url method accesses it correctly.
This issue began occurring after we upgraded Rails/Ruby/Paperclip. We're now using:
Ruby 2.1.5
Rails 4.2.0
Paperclip 4.2.1
Note that on development, files always save correctly (local filesystem). I have scoured Stackoverflow and Google to no avail. Please let me know if I can provide any additional information. Thank you!
EDIT:
Model:
has_attached_file :main_event_photo, {
:styles => { :original => {:geometry => "1280x800#", :format => 'png'},
:main => {:geometry => "640x400#", :format => 'png'},
:thumb => {:geometry => "330x220#", :format => 'png'}
},
:convert_options => {:original => '-quality 80',
:main => '-quality 80',
:thumb => '-quality 80'
},
:default_style => :main
}.merge!(PAPERCLIP_STORAGE_OPTIONS) # this is defined in the config/environments
validates_attachment_content_type :main_event_photo, :content_type => ['image/jpeg', 'image/png', 'image/gif', 'image/x-png', 'image/pjpeg']
validates_attachment_presence :main_event_photo
Form (basically):
<%= simple_form_for(#event, :url => { :action => #event.id.nil? ? "create" : "update" }) do |f| %>
<%= f.file_field :main_event_photo %>
<% end %>
Note we have many models with Paperclip attachments, and the issue occurs on each.
So this turned out to be the result of a bug. I upgraded Rails to 4.2.1.rc1 which was released last week, and the issue was resolved. If anyone wants more information, check out the thread on Github: https://github.com/thoughtbot/paperclip/issues/1772. It includes a workaround for those who can't upgrade Rails.

Why doesn't work Paperclip interpolations?

I am trying to make work Paperclip interpolations the whole afternoon, but still not success.
Here is how I have set up the Image model:
has_attached_file :image,
:styles => { :thumb => '300x300#',
:medium => "300x300>",
:original => "900x900>" },
:path => ":rails_root/public/images/:user_id/:style/:basename.:extension",
:url => "/images/:user_id/:style/:basename.:extension"
In /config/initializers/paperclip.rb is following:
Paperclip.options[:command_path] = "/usr/local/bin"
module Paperclip
module Interpolations
def user_id attachment, style_name
attachment.instance.user_id.to_s
end
end
end
But every time I save a file, the files is saved as
/images//original/file-name.jpg
The user's ID is missing.
What is wrong in this sample? I still cannot find the right config of Paperclip setup. I would be very grateful for every help.
Thank you
Try to add this in your Image model
Paperclip.interpolates :user_id do |attachment, style|
attachment.instance.user_id.to_s
end

Resources