Whats the best practice for creating and sending an email attachment using Rails API - ruby-on-rails

I need to know if I'm implementing the correct procedure when sending an email with an attached .xls document.
The attached .xls document would simple have the information provided in an object. ...ie: person.first_name person.last_name. The xls file will render the full names of the list.
I have a front-end React.js with a back-end Rails API.
I actually have it working in it’s most simple way but I’m not sure if this would be the best way.
Please let me know if there is amore efficient way of doing this.
Currently I have this setup: In my React Action Creator I have a fetch calling to a custom “list” method on my controller backend. In this controller I’m creating and writing the file like this:
File.open(“new_file”, 'w+') do | f |
c = #list.names do | name, data |
f.puts ( "#{name.first_name} #{name.last_name}")
f.close
end
end
The above code will create a file in the root of my application which I’m not sure if it’s best practice.
After this code runs the mailer sends out the email with the proper xls file attached .
My question is: What do I do with this newly created file on the root of my rails application. Is this normal to have and every time this runs the file is overwritten which is okay in my opinion. What if two different people on different devices run the code at the same time. Will there be a chance of the list being mixed up and one user getting the wrong list? I just feel like this is not right to create a file to my back-end Rails api whenever my user needs a list emailed to them. Even if I delete it right after it’s sent in the mailer.
Thank you for your help.

How about creating temporally files with the ruby API
Or if there is not a need to reuse the file use send_data
If you have thousand of files that need caching is worth thinking something like the official Rails cache api(you can cache any kind of file no just HTML )

Related

Passing PDF Generated through WickedPDF in ActionMailer to functions in other Modules

I am trying to send an email to people when they do a payment through my site. I am able to generate the attachment and send it along with the emails.
I need my application flow to be like this :
Generate attachment -> Send with email -> Send the attachment to Google Drive
The first and second steps are done. I am having some issues with the third step. For Google Drive, I have made a separate module using the Google APIs and it is working nicely.
The issue I am having is with passing the pdf object to the Functions declared in Drive from my ActionMailer. Instead of passing the pdf, the function is sending this Object.
ActionMailer::Base::NullMail:0x0x0x(something)
The Mailer by default only returns ActionMailer objects, is there any way I can override it to return the PDF which I generated in my Mailer? If there is not, what are some other ways I can do it?
You can fetch the file path from ActionMailer objects or database and manipulate the file directly in the third step.
I have solved the issue and updating the answer so others could benefit.
I was able to implement it through importing the render function from the ActionController itself.
Now from the view object I can just do view.render and perform the same parameters. I am using Rails 4, but as some people have told me this functionality has been simplified in Rails 5.
I used this code from here :
Rails: Render view from outside controller
view = ActionView::Base.new(ActionController::Base.view_paths, {})
view.render(file: 'template.html.erb')

Upload and process a spreadsheet without storing it permanently

I want to provide an option to export data via a spreadsheet. I don't want to store it permanently (hence there's no need of storage services like S3). What would the most most efficient and scalable way of doing this? Where can I temporarily store this file while it is being processed? Here's what should happen:
List item
User uploads spreadsheet
My backend processes it and updates the DB
Discard the spreadsheet
My 2 requirements are efficiency and scalability.
If I was you i would look for a way to parse the XLS/CSV on the front-end and sending JSON to your backend. This way you pass slow /intensive work to the client (scalability) and process only JSON on the server.
You can start here:
https://stackoverflow.com/a/37083658/1540290
I'm assuming you have a form with a file input to pick the xls file you want to process like this:
<input id="my_model_source" type="file" name="my_model[source]">
To process the xls you could use roo gem.
Option 1:
In some controller (where you are processing the file) you can receive the file like this: params[:my_model][:source]. This file will be an ActionDispatch::Http::UploadedFile instance. This class has the instance method path that will give you a temp file to work with.
So, with roo gem, yo can read it like this:
xls = Roo::Spreadsheet.open(params[:my_model][:source].path, extension: :xlsx)
Option 2:
The option one will work if your importing process is not too heavy.
If indeed, is too heavy you can use Active Job to handle the processing in background.
If you choose Active Job, you:
will lose the opportunity to use ActionDispatch::Http::UploadedFile's path method. You will need to generate the temp file on your own. To achieve this you could use cp command to copy the ActionDispatch::Http::UploadedFile's path wherever you want. After use it you can deleted with rm commnad
will lose a real time response. To handle this you could use Job Notifier gem
I have tried to show roughly what paths you can take.

How to show data from file without store data in DB

I'm new in RoR.
I want to upload xml file, parse it, analyze and show results on same or next page.
I read a lot of tutorials, but they describe how to upload file, parse, store data in DB.
For example: Upload and Parse a XML File with Ruby on Rails, Paperclip and Nokogiri
Could you, please, describe how to do that without store data in DB?
I think its something like this:
Make controller with two pages, make classes for data.
Call controller method from first page (with helper or without)
Upload and parse file and fill object with data from file
Show data from object on next page.
But I don't know is it right or not.
I will be very appreciate for manuals/tutorials/etc which can help me.

How to provide cid email attachments to embedded browser

I'm using embedded web browser from Bsalsa to write an email client in Delphi
I have a problem with cid embedded attachments such as:
<IMG src="cid:5D4219C71EAE43B1864AE9CB27C224A8#somehost">
I store the attachments in the database but can't figure out how to provide them to the browser. It seems custom moniker might need to be implemented but the documentation is scarce.
Any help would be appreciated.
I've implemented it using a "pluggable protocol" handler and it's easier thant it looks. Start here: http://msdn.microsoft.com/en-us/library/aa767916(VS.85).aspx and here: http://www.bsalsa.com/protocols.html
I am sorry I can't share the code I wrote but it's written for the company I work for and I have restrictions about it. Basically you need a com object that implements the proper interface to get the data and allow the web browser control read them.
That's IMHO the correct way to do it - altering the mail and storing temporary data may bring issue in the long run.
The simplest solution is to extract your "attachments" as requested into a temporary folder, then change the reference in the source to point to these temporary files, prior to being displayed. In the past I have used diHTMLParser to just this with great success.
If I remember correctly, the message contains these mime attachments along with an optional filename which doesn't always exist, but will have a mime type so you might have to have a translation table to get a default file extension for an attachment. Also, keep track of the files you place in your temp directory and clean up once your message window is closed. If you allow multiple messages opened at once, allow for name collisions and generate unique files.. it is common for signatures to have the same name, but be from different people... can be confusing if your message from John is signed Mary. :)

Accessing Word documents in a Rails app

I have a number of documents (mainly Word and Excel) that I'd like to make available to users of my Rails app. However, I've never tried something like this before and was wondering what the best way to do this was? Seeing as there will only be a small number of Word documents, and all will be uploaded by me, do I just store them somewhere in my Rails app (i.e. public/docs or similar) or should I set up a separate FTP and link to that? Perhaps there's an even better way of doing this?
If they're to be publically accessable, you definitely just want to stick them in public somewhere. Write a little helper to generate the URL for you based on however you want to refer to them in your app, for cleanliness (and so if you do change the URL later, for example to bucket your files to keep your directory sizes under control, you don't have to change links all over your app, just in one place.
If, on the other hand, your files are only for logged-in users, you'll need to use something like send_file to do the job, or one of the webserver-specific methods like the X-Sendfile header to check the user is authorised to view the file before sending it back to them.
I would do as you suggested and put them in public/docs. If you are planning on making an overview/index page for the files and link directly to them it would be easier if they were stored locally instead of a remote FTP server. However, since you are the one who will be uploading and maintaining these files, I think you should go with the option that's easiest for you.

Resources