Clear out Active Storage - ruby-on-rails

How can I delete all Active Storage records from my database but WITHOUT removing the actual files themselves (with the exception of the generated variant files).
I've tried several options but either get stuck removing the records or the variant files.
I saw online that variants were stored in a variants folder but when I check my S3 bucket they just show up in the root. Why is that? If I had them in a variants folder I could easily delete that.

Related

Should I delete uploaded files from the file system on my own?

I have a rails app where the user can upload files. The files get uploaded to an external cloud service by a backgroud jobs. It's vital for my app that the files won't get stored in the file system after they've been uploaded. Not right away, in general -- they must not remain in the file system.
Should I delete them on my own? Or will get deleted automatically?
Also, debugging my app, I noticied this for an attachment params:
[2] pry(#<MyController>)> my_params.tempfile.path
"/var/folders/qr/0v5z71xn7x503ykyv1j6lkp00000gn/T/RackMultipart20181007-10937-3ntmgg.png"
That file gets stored not in "/tmp" but in "/var" and that means that it won't get deleted automatically, right?
Note that I'm not using paperclip for this task.
You are right the files won't get deleted automatically.
You have to delete the file explicitly at some point in time.
It depends how you set it up. If you used Tempfile to save it then yes the files will be deleted when the object is garbage collected. If not then it probably won't be deleted.
If the files get stored on an external service it might be worth setting up ActiveStorage which allows you to directly upload to external storage providers without the file ever touching your server.

Rails File Upload - Scan files; and separate folders for each user

Does Paperclip scans the files for errors, malicious software, viruses before uploading to database? If no, what are the viable solutions.
And, is it better to first create a separate folder for each user before they upload files and store in their respective folders? What are the merits and demerits of it? Is it possible to specify this with Paperclip?
Thanks
Re viruses etc, this might be useful - Rails / Heroku - How to anti-virus scan uploaded file?
Re storing each user's files in a seperate folder: the conventional way would be to store every FILE in a separate folder, and then link the files to the user via the database (eg a user_id field on the file records). As far as merits and demerits go, besides it not being conventional, one thing to bear in mind would be that if a user's files are stored in a single folder, then if they upload a two files with the same name then the second would overwrite the first (unless of course you put them in separate folders within the user's folder). This could be a good thing or bad thing depending on your requirements.
BTW - a slightly pedantic note: files aren't uploaded to the database (at least not normally) - they are uploaded to a filesystem, and a corresponding record is created in the database. The files don't go into the database (as i say, usually: it is possible to store files as blobs in the DB but it's not good practise and not usual).

how can I open a sqlite file in ios for reading without copying to documents?

I got an app I'm working on that uses static data from a sqlite database to do various things, While I only need read only access to the database, depending on the episode they pick from the first screen I want it to use a different database file and I want the list of available episodes to be updateable on the fly. and I got help to get the list of available episodes updated, and the proper content downloaded and stored in separate folders, So I know I could when the episode is selected delete the sql file in the documents folder and copy in the new one each time and that would work well enough for what I'm trying to do. but it seems like a bit much extra work to have to check for file, delete file, copy in new one. then open it from there each time the user wants to pick a different episode. and I don't want to put all the sql files together as that will be a bigger hassle then the first route especially if this app stays around long enough to have a long list of episodes.
so my question here is: can I get at least read-only access to an sql file that I've downloaded (or one in the bundle for testing) with out having to first copy it to the documents? and if so how would i open the file?
Can I get at least read-only access to an SQL file that I've downloaded (or one in the bundle for testing) without having to first copy it to the documents directory?
Yes. Files in the app bundle are readable (if they weren't, there would be no point in storing files in the bundle).
And if so, how would I open the file?
It's not clear what you're asking here - if you want to perform SQL queries on the file, you should use the sqlite3 library which is available on iOS.

File repository in ruby on rails

I would like to create a simple file repository in Ruby on Rails. Users have their accounts, and after one logs in they can upload a file or download files previously uploaded.
The issue here is the security. Files should be safe and not available to anyone but the owners.
Where, in which folder, should I store the files, to make them as safe as possible?
Does it make sense, to rename the uploaded files, store the names in a database and restore them when needed? This might help avoid name conflicts, though I'm not sure if it's a good idea.
Should the files be stored all in one folder, or should they be somewhat divided?
rename the files, for one reason, because you have no way to know if today's file "test" is supposed to replace last week's "test" or not (perhaps the user had them in different directories)
give each user their own directory, this prevents performance problems and makes it easy to migrate, archive, or delete a single user
put metadata in the database and files in the file system
look out for code injection via file name
This is an interesting question. Depending on the level of security you want to apply I would recommend the following:
Choose a folder that is only accessible by your app server (if you chose to store in the FS)
I would always recommend to rename the files to a random generated hash (or incremntally generated name like used in URL shorteners, see the open source implementation of rubyurl). However, I wouldn't store them in a database because filesystems are built for handling files, so let it do the job. You should store the meta data in the database to be able to set the right file name when the user downloads the file.
You should partition the files among multiple folders. This gives you multiple advantages. First, filesystems are not built to handle millions of files in a single folder. If you have operations that try to get all files from a folder this takes significantly more time. If you obfuscate the original file name you could create one directory for each letter in the filename and would get a fairly good distributed number of files per directory.
One last thing to consider is the possible collision of file names. A user should not be able to guess a filename from another user. So you might need some additional checks here.
Depending on the level of security you want to achieve you can apply more and more patterns.
Just don't save the files in the public folder and create a controller that will send the files.
How you want to organise from that point on is your choice. You could make a sub folder per user. There is no need to rename from a security point of view, but do try to cleanup the filename, spaces and non ascii characters make things harder.
For simple cases (where you don't want to distribute the file store):
Store the files in the tmp directory. DON'T store them in public. Then only expose these files via a route and controller where you do the authentication/authorisation checks.
I don't see any reason to rename the files; you can separate them out into sub directories based on the user ID. But if you want to allow the uploading of files with the same name then you may need to generate a unique hash or something for each file's name.
See above. You can partition them any way you see fit. But I would definitely recommend partitioning them and not lumping them in one directory.

Rails & Dragonfly: Cleaning up unused images

I'm working on cleaning up an old Rails 2.3.5 app that uses Dragonfly to store its images.
I have a feeling there are far more images in the filestore than records in the database, but due to Dragonfly's less than transparent naming scheme I have no idea how to find out which files in the filestore belong to actual records.
Anyone have a good idea how I can clean this up? I'd love to get rid of several gigabytes of unused data.
You could look up the media records in your database where you should find a column postfixed with "_uid". This column contains the relative path to your media files in your media folder. You could then remove the files that cannot be found in your database. Be careful: as I can see there is one additional file postfixed ".extra" per media file that you should keep (but I don't know what it is for).
I am thinking about implementing such a functionality with a "Cleanup media data store" Button in my admin interface. I didn't try this out yet, though.

Resources