Attach a pdf in asset pipeline using ActionMailer Rails 4 - ruby-on-rails

I'm trying to attach a file to an email. The file is in assets/downloads/product.pdf
In the mailer, I have:
attachments["product.pdf"] = File.read(ActionController::Base.helpers.asset_path("product.pdf"))
I've tried:
attachments["product.pdf"] = File.read(ActionController::Base.helpers.asset_url("product.pdf"))
...and even:
attachments["product.pdf"] = File.read(ActionController::Base.helpers.compute_asset_host("product.pdf") + ActionController::Base.helpers.compute_asset_path("product.pdf"))
I always get the same error:
EmailJob crashed!
Errno::ENOENT: No such file or directory - //localhost:3000/assets/product.pdf
...or a variation on the theme. But even when I try using asset_url in the view or just put the url in the browser it works:
http://localhost:3000/assets/product.pdf
I've also tried using straight up:
File.read("app/assets/downloads/product.pdf")
File.read("downloads/product.pdf")
...which works in dev environment but not on staging server (heroku). Error is still:
Errno::ENOENT: No such file or directory - downloads/product-market-fit-storyboard.pdf
Also tried:
File.read("/downloads/product.pdf")
File.read("http://lvh.me:3000/assets/product.pdf")
...don't work at all.
Ideas?

you should use syntex like this.it is work for me may be will work for you also.
File.open(Dir.glob("#{Rails.root}/app/assets/downloads/product.pdf"), "r")

When using mailer, you shouldn't use assets pipline. Asset pipeline would be useful if you wanted to have link to a file inside your email. When rendering an email, action mailer has access to files in app directory.
Please read about attachments in action mailer guide. As you can see, you just need to pass path to a file, not url:
attachments['filename.jpg'] = File.read('/path/to/filename.jpg')

Related

Can't read image path: No such file or directory # rb_sysopen - /assets/

I have an image named test.jpg in my assets/images folder.
I'm trying to read the image in my controller:
image_path = ActionController::Base.helpers.asset_path("test.jpg")
image_data = File.read(image_path)
I get the following error:
No such file or directory # rb_sysopen - /assets/test-80cc818a7ee3f5d3cab23996fb09f4685b38b78258084a1ff23eca1c626646f6.jpg
Any ideas? Why is it appending that code to my image url? Can I get rid of it so it can read the original image url?
Thanks!
So, basically asset_path returns a URL-path, relative to the root domain - ie. "/assets/test-{SHADigest}.jpg".
That path is not a path for the file system, that File.read will accept, therefore, on unix systems you're trying to access the file system at /assets/xyz, like had it been /home/xyz-path.
What you can do, is either read from file system, raw file (Ignoring any thing the asset pipeline may or may not be set up to do)
image_path = Rails.root.join("assets", "images", "test.jpg")
image_data = File.read(image_path) # Maybe check with File.exist?(image_path) as well.
Or you can read from its own webserver, with any HTTP Client tool (RestClient, Net::HTTP or alike), and use asset_url instead of asset_path.
This won't work in rails console unless the server is "accidentally" running, and reachable on config.asset_host from where ever the rails console is running.

In Rails I want to read excel file form Live Path like http://www.carsa.jp/admin/data.xlsx

I wants to read a excel file existing on Live URL of another website.
When I hit that URL in browser file is downloading. While in my rails app it is giving below error
No such file or directory # rb_sysopen - http://www.carsa.jp/admin/data.xlsx (Errno::ENOENT)
My Rails app code is as below
data = Roo::Excelx.new('http://www.carsa.jp/admin/data.xlsx')
header = data.row(1)
puts header
Note: If I download file and place it within my application it is working fine but the requirement is to read it from the third-party website in a scheduled job as per the above script.
data = Roo::Excelx.new('lib/data.xlsx')
header = data.row(1)
puts header
Try using Roo::Spreadsheet.open instead of Roo::Excelx.new. According to the Roo Readme:
Roo::Spreadsheet.open can accept both paths and File instances.
This should do the trick:
Roo::Spreadsheet.open('http://www.carsa.jp/admin/data.xlsx')

Rails PDFKit - Errno::ENOENT (No such file or directory) when using to_file

Whenever I try to generate a pdf using to_file, the process will just hang, and when I stop the development server I get Errno::ENOENT (No such file or directory - path/to/pdf). However, I am able to render a pdf inline using to_pdf. I'm also able to generate PDFs from the command line in the same folder that I'm trying to generate them in with to_file.
I'm using Rails 3.2.12 and pdfkit 0.8.2. I've tried using wkhtmltopdf versions 0.9.6 through 0.12.4. I'm on Ubuntu 14.04.
Example from controller:
html = render_to_string(:action => "show.html.erb", :formats => :html)
kit.stylesheets << "{Rails.root}/app/assets/stylesheets/stylesheet1.css"
kit.stylesheets << "#{Rails.root}/vendor/assets/stylesheets/stylesheet2.css"
kit.to_file("#{Rails.root}/folder_to_write_to/generated_pdf.pdf")
Turns out the issue was the asset pipeline conflicting with wkhtmltopdf. Added config.threadsafe! to development.rb and it started working.
Another issue can be the default options passed. For example, when I left the default print_media_type option in place, found this message in the log:
The switch --print-media-type, is not support using unpatched qt, and will be ignored."
Only when I override that does it work for me, either in the initializer or like so:
PDFKit.new(html, {print_media_type: false})
The message says it'll be ignored, but it wasn't. It was causing the file to not get generated.

Ruby on Rails copy S3 file with special characters (%C5) in path

I have a problem with my attachment system on web page. I store them on amazon S3 using paperclip. I have an option to copy attachment to new file. Everything works fine until there are polish special characters in title, like: ŁĄKA.jpg. Then I get an error:
Saving error: Appendix Paperclip::Errors::NotIdentifiedByImageMagickError
/Users/michal/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.5/lib/active_record/validations.rb:79:in `raise_record_invalid'
/Users/michal/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.5/lib/active_record/validations.rb:43:in `save!'
My code:
instance.appendixes.select {|a| a.temporary? && !a.appendix.exists?}.each do |a|
a.appendix = S3File.new(a.s3path)
a.process = false
a.appendix_url = nil
puts "CREATING NEW FILE from (temporary?) appendix: #{a.id}, path: #{a.s3path}, is_public: #{a.is_public}, determine_is_public: #{a.determine_is_public}"
a.is_public = a.determine_is_public
logger.debug("CREATING NEW FILE from (temporary?) appendix: #{a.id}, path: #{a.s3path}, is_public: #{a.is_public}, determine_is_public: #{a.determine_is_public}")
a.save! # bo delayed_job
end
I'm getting error on a.save! when path is like: appendixes/appendixes/242/original/%25C5%2581A%25CC%25A8KA.jpg, but works like charm when it is: appendixes/appendixes/243/original/laka.jpg or another file name without polish letters. Anybody had this kind of problem or have suggestions how to fix it?
Ok, I found what was wrong. I had to replace in a.s3path, the last part with original name (łąka.jpg) and everything works fine. So when I have:
S3File.new(appendixes/appendixes/243/original/łąka.jpg) it works good and finds the correct file on s3 server.

Set System Directory Rails Production Environment

I have an app that works fine in on my development machine, but on my production server it uses a broken link to serve an image served using the Paperclip Gem.
Production environment is Linux(Debian), Apache, Passenger and I am deploying with Capistrano.
The app is stored in (a symlink that points to the public folder of the current version of the app deployed using capistrano):
/var/www/apps/root/appname
However, when I try and access it on the production server, the Apache error log displays this as the path it is looking in:
/var/www/apps/root/system
The correct path, however, is:
/var/www/apps/appname/shared/system
One option available to me is to create a symlink in root that directs system to the correct path, but I don't want to do this in case I want to deploy another app in the same root dir.
The url for this request is generated by rails, but Apache is what fetches the static resource (image files), so I have tried placing the following in my config/environments/production.rb:
ENV["RAILS_RELATIVE_URL_ROOT"] = '/appname/'
Which has resolved all other pathing issues I've been experiencing, but when rails generates the url (via the Paperclip gem), it doesn't seem to use it.
How can I set it so Paperclip uses the right path and only uses it production?
I've a workaround, add this as one of initializers:
config/initializer/paperclip.rb
Paperclip::Attachment.class_eval do
def url(style_name = default_style, options = {})
if options == true || options == false # Backwards compatibility.
res = #url_generator.for(style_name, default_options.merge(:timestamp => options))
else
res = #url_generator.for(style_name, default_options.merge(options))
end
# replace adding uri before res, minus final /
Rails.application.config.site_relative_url[0..-2]+res
end
end
At the moment Paperclip doesn’t work with ENV['RAILS_RELATIVE_URL_ROOT'] and the. You can follow the issue here:
https://github.com/thoughtbot/paperclip/issues/889

Resources