views:

218

answers:

2

I have multiple applications (an admin application, a "public"/non-admin application and a web service application) that all share a single database.

I've gotten the applications to share models and other code where appropriate, so I don't have multiple copies of the same code in each. However, the one task that I've yet to configure is how to share files that get uploaded between applications. I'm using Paperclip to successfully upload files to my applications, but if it uploads the files to the application doing the upload.

Ideally, I'd like to be able to serve all the files from the web service. My idea was that I'd need some type of task executed every time a new file is uploaded to any of the applications to have the file created in the file structure of the web service.

I know I could easily accomplish serving files from a single application if I loaded the files into the database (which is how I accomplished this in a similar application suite), but I'm not sure if that's the best route to go for managing/serving the files. Another idea I had was storing the files in the database and having the web service manage "serving" them and having it create the file on the disk on the first request. After the first request for the file, the web service would serve the file from the disk rather than from the database.

Does anyone have any ideas on what the best way to accomplish this might be? Or any better ideas?

Thank you in advance for any feedback anyone might have on the subject.

A: 

Are you running all apps on the same UNIX/Linux system? Have you tried creating symbolic links to share the folder that contains the images? The goal is to save all images to the same location. Eliminating the need to throw in complicated hooks for attachment creation.

Paperclip by default stores things at :rails_root/public/system/:attachment/:id/:style/:filename If you're sharing a database you won't have to worry about collisions. And you just need to create a system folder to be used by each app.

You can use one app's public/system folder as the master, or create an entirely new one. From this point on all other system folders that aren't the master one will be referred to slave folders. Once you've chosen your master it's as simple as moving everything in each slave folder to the master folder. Deleting the slave folders and replacing them with a symbolic link to the master folder.

Sample command set to migrate and replace with symlink given the paperclip defaults. It's probably a good idea to stop the server before attempting this.

$ mv /path/to/slave/project/public/system/* /path/to/master/system
$ mv /path/to/slave/project/public/system.bak
$ ln -s /path/to/master/system /path/to/slave/project/public/system

Once you're sure the migration is sucessful you can remove the backup:

$ rm /path/to/slave/project/public/system.bak
EmFi
+1  A: 

I'd recommend putting them in a shared location that is served directly by your front end webserver (not Rails) if you have that kind of setup, in this example it's serving up a location called files that points at a folder on disk. Then in your paperclip options, change the save location.

has_attached_file :image,  
   :url => "/files/:basename.:extension",  
   :path => "/var/htdocs/public/files/:basename.:extension"
MattMcKnight
Thanks for the input Matt. I think this sounds like the ideal solution, how would the URL's for the files be affected?
michaeldelorenzo
I ended up using this solution. After taking a peek at the Paperclip plugin's source code, I noticed that you can set a fully qualified domain name as the attachment's URL.I configured a global variable loaded from the appropriate environment configuration file to set the domain appropriately.Thanks for the suggestion Matt.
michaeldelorenzo