I do not know anything about Ruby on Rails, but I am involved with re-writing an application developed with it by someone else a while ago. I have access to the source code and, while I like to think I know programming (C/C++, etc.), I’m having difficulty trying to figure out Ruby on Rails. And I guess the reason why I can’t figure it out is because the details of it is hidden within a library (paperclip).
(Short version: I want to match filenames in a database column with the physical location of files on disk.)
With my limited knowledge, I know the following…
The application has a Gemfile.gem
with this entry: ‘paperclip’, ‘4.3.0’. I’ve looked at the development history of paperclip
and realise that this is from April 2016. So, it seems pretty old…
I have a PostgreSQL database with fields such as:
- attachment_file_name
- attachment_content_type
- attachment_file_size
- attachment_updated_at
And all of this matches the variables mentioned here in the documentation.
The values under attachment_file_name
in the database are just filenames, with no paths.
On disk, the files are stored in directories such as attachments/000/003/335/original/abc.txt
, which looks exactly like the example in the documentation. So, I guess I am fairly sure that paperclip
is being used.
How does the filename translate to the above path?
And, more importantly, if I have a set of a few hundred files, I would like to print out the full path for each file. There are duplicates in the filename that result in different paths. So I guess the calculation (hash function?) is done using both the filename and maybe the contents of the file.
Can someone offer suggestions about how to do this and/or what in the code I should be looking for?
I guess my question is similar to this Issue in the repository, which pointed the author of that Issue to StackOverflow (of course, that was 7 years ago).
Thank you! Any help would be appreciated!
It’s easier with an example:
class User < ActiveRecord::Base
has_attached_file :attachment
validates_attachment_content_type :attachment, content_type: /\Aimage\/.*\z/
end
Attach a file:
>> User.create!(attachment: File.open("avatar.png"))
TRANSACTION (0.1ms) begin transaction
User Create (0.3ms) INSERT INTO "users" ("attachment_file_name", "attachment_content_type", "attachment_file_size", "attachment_updated_at") VALUES (?, ?, ?, ?) [["attachment_file_name", "avatar.png"], ["attachment_content_type", "image/png"], ["attachment_file_size", 8229], ["attachment_updated_at", "2023-12-01 05:14:12.369915"]]
TRANSACTION (5.4ms) commit transaction
=> #<User id: 1, attachment_file_name: "avatar.png", attachment_content_type: "image/png", attachment_file_size: 8229, attachment_updated_at: "2023-12-01 05:14:12.369915603 +0000">
This is the default path where file is stored:
>> Paperclip::Attachment.default_options[:url]
=> "/system/:class/:attachment/:id_partition/:style/:filename"
$ ls public/system/**/*.png
public/system/users/attachments/000/000/001/original/avatar.png
public/
system/
users/ - :class # `User.name.underscore.pluralize`
# https://github.com/thoughtbot/paperclip/blob/main/lib/paperclip/interpolations.rb#L88
attachments/ - :attachment # pluralized attachment name
# vvvvvvvvvv
# `has_attached_file :attachment`
# https://github.com/thoughtbot/paperclip/blob/main/lib/paperclip/interpolations.rb#L191
000/000/001/ - :id_partition # id padded with zeros and split in 3 groups (9 digits total)
# https://github.com/thoughtbot/paperclip/blob/main/lib/paperclip/interpolations.rb#L174
original/ - :style # "original" is default, this is what you've uploaded
# https://github.com/thoughtbot/paperclip/blob/main/lib/paperclip/interpolations.rb#L197
avatar.png - :filename
If you can only work from the database side
sqlite> select * from users;
+----+----------------------+-------------------------+----------------------+----------------------------+
| id | attachment_file_name | attachment_content_type | attachment_file_size | attachment_updated_at |
+----+----------------------+-------------------------+----------------------+----------------------------+
| 1 | avatar.png | image/png | 8229 | 2023-12-01 05:14:12.369915 |
+----+----------------------+-------------------------+----------------------+----------------------------+
public/
system/
users/ - :class # most likely the same as table name
attachments/ - :attachment # attachment_file_name
# ^^^^^^^^^^s
000/000/001/ - :id_partition # padded id - you'll need to work that one out
original/ - :style # "original" - this is not in the db
avatar.png - :filename # attachment_file_name