Rails 4 static assets in public/ or app/assets/

Taylor j. Eke picture Taylor j. Eke · Nov 22, 2013 · Viewed 19k times · Source

Sorry if this is a lengthy buildup to a simple question, but I wanted to get my thoughts clear.

I've used Rails 4 on a couple projects now and I've been using image_tag('/assets/image.png') to get around the changes to how asset path helpers work in Rails 4. That is until today when I decided to learn more about the changes and found this first change note in sprockets-rails. I've also noted that the ASSET_PUBLIC_DIRECTORIES in /actionview/lib/action_view/helpers/asset_url_helper.rb#L170 in Rails helpers only point to public folders. It became pretty obvious to me that if you are accessing static files, Rails wants you to use use the public folder.

So now that I've figured this out, I just can't understand why the edge rails docs clearly state this:

In previous versions of Rails, all assets were located in subdirectories of public such as images, javascripts and stylesheets. With the asset pipeline, the preferred location for these assets is now the app/assets directory.

image_path in practice generates a uri to the public/images folder which is totally contrary.

And to sum this all up I do need to use all available helpers and digest builders, because I end up deploying my assets to S3 with asset_sync.

So my question is just; is there a correct place to put images/non-compiled assets and use asset_path helpers? All the documentation and every other stack overflow conversation is about people using the app/assets folder, but sprockets-rails wants us to use public for non-digest assets. Are the docs and info on the web just in need of an update, or are others just making due with prepending all asset paths with /assets/?

UPDATE: I think I did actually have an issue where I wasn't restarting my development server and images in app/assets/images were not showing up so it would fallback to public. Also note that I was using asset helpers in my paperclip default_url (which is referenced as the way to point to assets in several stack overflow answers I found, however using the asset path helpers with interpolated options in paperclip will also fallback to public, because the uninterpolated asset name wouldn't be found as an existing file obviously.

Answer

Amar H-V picture Amar H-V · Feb 5, 2014

When you use rake assets:precompile, Rails moves all of the assets from your app/assets folder, to public/assets. This is as a normal browser does not have access to your app directory, but does have access to public.

So, to answer your question, here are my thoughts. If your images are for your sites layout e.g logos or backgrounds, then you should store them in the app/assets/images directory, however, if the images are user generated, such as profile images, then these should be stored directly in something such as public/images. Ideally you would store those in S3 or a CDN, but you're already doing that.

As a bonus, Carrierwave, a Rails image upload gem, uses a public/images type path as the default store for its images, as you can see in their config file:

    # Override the directory where uploaded files will be stored.
    # This is a sensible default for uploaders that are meant to be mounted:
     def store_dir
     "images/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
     end

Hope this helps!