With the introduction of the new directory structure in 3.1 (i.e. app/assets/), should app images (logo, banner, icons, main bg, etc) still be stored in public/images or should they go into app/assets/images?
Someone mentioned:
I would be shocked if anything in
app/assets can be served publicly -
that wouldn't make sense from either a
security viewpoint or from honoring
the convention of the public
directory. Since you need these flash
files to be publicly accessible, you
should store them in public.
Valid point. Which brings me to the question:
Based on above understanding. What about the app images? If images such as logo, banner, main background, icons are considered public, why is there an images directory in app/assets?
Or should we still put these types of images in public/images. If so, what is the images dir in app/assets used for?
Note: I haven't looked at Rails 3.1 yet...
As far as I understood DHH's keynote, app/assets was introduced so you could structure your application in a better way. But there's nothing wrong with storing images in public/images. Thanks to Michiel for pointing out that public/images will no longer be with us in Rails 3.1!
The public folder will the replaced by the assets folder. That's the folder that your web server will point to. Files from app/assets, lib/assets or other places will be copied (images) or compiled (css, js) to assets.
That means that assets is now considered a build directory, and you shouldn't store anything there - you might even decline to put it under version control, and just have the server generate or copy the images and css and scripts when you deploy.
See also: http://blog.nodeta.com/2011/06/14/rails-3-1-asset-pipeline-in-the-real-world/
Related
What's considered an "asset" in the Ruby on Rails universe?
Are user generated files, such as images uploaded by the user, considered assets? Where should they be stored in the standard file structure of a Rails project? Should they be kept clear of any asset related directories like:
app/assets
lib/assets
public/assets
Relevant: The Asset Pipeline
Generally asset is anything that browser loads after it gets the HTML page. Meaning javascript, css and any images. But as you pointed out there are two different image types in a rails project.
1) the images related to your css and layout design, those go under the app/assets/images
2) the images that your users upload, those normally go into the public/system or public/uploads folder depending on what you use to receive the uploads
The lib/assets (or sometimes vendor/assets) is where you supposed to place js/css/images related to your front-end design and provided by third party libs. Say if you want to pull in some css or a js framework, that were you should place it.
And finally public/assets is where rails will compile your layout assets from the app/assets and vendor/assets folders when you run rake assets:precompile task for production.
To have it short, your design stuff goes to app/assets, and the user uploads go into public/system
User-uploaded files are not part of assets, and should definitely be kept clear of asset-related folders. You should put them somewhere in your public directory. I put mine in public/uploads, which is a common convention. And then you should ignore those files in git (or whatever VCS you're using).
Assets are basically: javascript, stylesheets, fonts, and images which are part of the site design itself, not part of the user-uploaded content.
I have a question relating to how precompiled assets are utilized in a production environment. What about general file attachments as a part of the model? For example, I have the model "Event". You can have n attachments to the model, and they can be any file you want. Typically they are either image files or PDF files, but they can also be Excel files for example. These files are to be displayed as links to the user and the user can click the link to open the file. The attachment files are stored in the /assets directory in the following manner, alongside the standard assets:
/assets
/images
/javascripts
/stylesheets
/attachments
/events
/11
poster.jpg
event-details.pdf
Now as I understand it, when I run the precompile method, Sprockets generates gzipped/MD5'ed versions of the files to be served...how do I deal with these attachment files? If I run the precompile method, everything gets gzipped...but when I add/remove attachments further down the road through the web interface, some will be gzipped and others won't. What's the best way to deal with this?
I gave up trying to figure out a way around it and just set all the attachments as well as paperclip attachments to be physically put in the /public directory. From my vantage point, this removes the benefit of compressed assets, but whatever.
After reading about how rails is handling image assets, I am confused and am having trouble deciding where to keep uploaded images in my app's directory tree. If a user has uploaded an image to my rails app, should I make the image_save_path /assets/images/ or /public/images ?
My concern/question: If I want to allow users to make their images public when they choose to do so, should an uploaded image that is 'un-published' (image is served only if current_user == image.owner) be considered more protected if it resides in assets/images instead of public/images? Equally protected? Less protected somehow?
Am I right to assume that the benefit of using the asset pipeline for images is simply that the file names get hashed in production mode and that's it? Is there some implied additional or diminished security here in terms of how the resource is served? Is this more a matter of subtle opinion or does the rails convention have something to say here?
Thanks!
EDIT1:
How would you handle uploaded content that you want to make available to the uploading user, but not discoverable to guests or other users? Should (can?) one store uploaded content outside the tree under web_root ?
Application assets are those assets that are part of your application, such as backgrounds and icons (in the case of images). The asset pipeline has nothing to do with user-uploaded images. I'd suggest to keep them separated, serve them from separate CDN if needed.
The hashing of filenames in the asset pipeline is done only during asset compilation, so a link to a specific image is made unique for the image contents. This helps to avoid setting complex caching headers to images and other assets, as when the image changes, the filename changes too, and the cached version won't be used at all.
All this does not apply to user-uploaded images, you are not going to compile on-the-fly the assets for their images.
I've found several sites online that explain the DIR structure of a Rails app, but I'm still not clear on a few, mainly:
/vendor
/lib
/public
What should go where? I want to know the best practice. For example, I have jQuery plugins, should those be located in /vendor? /public? /lib? I've read all 3 from different sites online.
Thanks
Vendor is third party code / libraries, so, yes, a good place for jQuery plugins.
Public is for static assets, stuff that gets no benefit from being in the asset pipeline.
Lib is generally used to contain your code that is not specific to the app. i.e. stuff you use in multiple apps. There is a trend to put domain logic in lib e.g. domain classes not based on ActiveModel. Gary Bernhardt (https://www.destroyallsoftware.com/) is a proponent of this.
Typically the contents of /public are directly served by the web server (nginx, apache etc.) without intervention from rails, so traditionally all of your static assets (images, stylesheets, javascripts etc.) went in here. You can still put your javascript in there but it's a bit old fashioned.
Rails 3.1 introduced the asset pipeline which changed all of this. Assets in app/assets, lib/assets and vendor/assets all get servers up by the asset pipeline. Normally your application specific assets would go in app/assets and 3rd party libraries (such as a query plugin) would go in vendor/assets. If you were developing your own set of jquery plugins you might put them in lib/assets. Assets will 'work' no matter where you put them though - it's just a question of organisation.
Gems can also have their own asset folders, for example the jquery-rails gem bundles jquery and allows your app to serve up jquery without actually copying it into your app. I find this even neater than putting things in vendor/assets.
I've developed a simple app to display images in a series of subdirectories based on querystring input. (I more or less built my own Rails version of 360Works SuperContainer, for FileMaker.) I have copied a few test directories into public/images and everything seems to be working just great, but this app needs to operate over upwards of 60gb of images, and putting them all into the public/images folder isn't going to really be feasible.
Other than hard-coding the path into my model, how can I set a configuration option to specify a different default directory for the images folder?
I think you can change the asset_host field :
http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#M001688