Am I handling the 'public' directory the right way? - ruby-on-rails

I am using Ruby on Rails 4.1.1 and I want to add a linked image - my app's logo - in email messages but I had a doubt since my previous question.
By using files located in the public directory it seems that to link to an image in your Asset Pipeline you can use
link_to(LINK_TEXT_OR_IMAGE_TAG_HELPER, image_path(IMAGE_NAME))
but for those located in the app/assets it seems do not work the same, at least in rendered email messages in production mode. All assets that are compiled in Production have a fingerprint ID... is the fingerprint causing the load of static assets to do not render images in email messages?
I doubt since I would like to access images from both browser and email. I tried to solve the issue by moving the image from app/assets/images/logo.png to public/images/logo.png and by changing statements in my application.css.scss file from image-url("logo.png") to url("/images/logos.png"). However I do not know if I am following "the Rails way" or a "best practice". Do I? Should I add to the public directory all assets that I plan to use outside my application and in the app/assets directory all assets that I plan to use internally to my application?

For emails, it almostisn't any different compared to standard Rails views.
You can link to an image in your mailer using the image_tag helper you'd normally use in regular views as well:
<%= image_tag('some_image.jpg') %>
You also need to tell Action Mailer where it can find the assets, because it will use absolute URLs to refer to your images:
config.action_mailer.asset_host = 'http://www.example.com/'

Related

how to have assets other than js and css files in rails

I have some object files which I want to have them in my JS codes I put them under app/assets/3d-models and when I try to get a link to it I use:
<%= asset_path("3d-models/splits2/xxx.obj") %>
But the output is /3d-models/splits2/xxx.obj which obviously the 404 NOT FOUND is the result(i.e the asset not found, the wrong link!)
Question:
How can I get an access link to a file other than common files used in rails' assets?
You can have different assets. Just place them into assets folder and link to them correctly.
Rails are using assets pipeline. This is a concept, which provides a better way to serve some static files to a website. In Rails it is implemented by Sprockets gem. Please read more here.
You can also have other static files directly in public folder and link to those files anywhere from your app. This will not be included in assets pipeline.
If you use assets_path helper method, then there is a fingerprint added to a file so the URL to the file is different then.
Please check this section.

Serving images in rails

For every version of my app, I upload my assets to the cloud CDN, and the images on the website are loaded as something like imagename-somehash.
I have static images that are large, i.e like carousel images, which don't change often or at all. So even when the app changes, they can remain cached by clients who previously visited the website.
How would one do that? Any images I have under app/assets folder gets upload to CDN with the imagename-somehash format, so the image changes with every version of the app.
I'm using rails 4.2. Is this possible?
In rails guides there is an article What is Fingerprinting and Why Should I Care? which gives some insights about that hash on the end of a file and how it works.
Check your environments files. In production you may want config.assets.digest to be true.
You can put these images in public folder and can mention full url in views for these images
OR You can also put it on
vendor/assets/images
but in that case you would have to disabled precompile path
If you want to serve only some assets from your CDN, you can use custom :host option your asset helper, which overwrites value set in config.action_controller.asset_host.
<%= asset_path 'image.png', host: 'mycdnsubdomain.fictional-cdn.com' %>

Getting 404 for Rails Static Assets

I'm using Carrierwave to handle file uploads. Files get stored under public/uploads/. Project uses Ember.js templates, and the img tags point to the proper src. (I've verified that the files are present at those paths.) However, the server returns a 404 for each.
It looks like this is a common problem, and the common solution is to:
config.serve_static_assets = true
However, this isn't working. I'm still getting 404s. Any other ideas about how to deal with this?
It should be noted that I'm not using Apache or nginx.
Rails no longer compiles the assets without digests. In order for this to work properly, you need to use a rails helper to include the proper asset name (with the digest), or use a gem like https://github.com/alexspeller/non-stupid-digest-assets as a workaround.

Rails 3.1 and Image Assets

I have put all my images for my admin theme in the assets folder within a folder called admin. Then I link to it like normal ie.
# Ruby
image_tag "admin/file.jpg" .....
#CSS
.logo{ background:url('/assets/images/admin/logo.png');
FYI. Just for testing I am not using the asset_path tag just yet as I have not compiled my assets.
Ok all good so far until I decided to update an image. I replaced some colors but on reload the new styled image is not showing. If I view the image directly in the browser its still showing the old image. Going one step further I destroyed the admin images folder. But it has broken nothing all the images are still being displayed. And yes I have cleared my cache and have tried on multiple browsers.
Is there some sort of image caching going on? This is just local development using pow to serve the pages.
Even destroying the whole images folder the images are still being served.
Am I missing something?
In 3.1 you just get rid of the 'images' part of the path. So an image that lives in /assets/images/example.png will actually be accessible in a get request at this url - /assets/example.png
Because the assets/images folder gets generated along with a new 3.1 app, this is the convention that they probably want you to follow. I think that's where image_tag will look for it, but I haven't tested that yet.
Also, during the RailsConf keynote, I remember D2h saying the the public folder should not have much in it anymore, mostly just error pages and a favicon.
You'll want to change the extension of your css file from .css.scss to .css.scss.erb and do:
background-image:url(<%=asset_path "admin/logo.png"%>);
You may need to do a "hard refresh" to see changes. CMD+SHIFT+R on OSX browsers.
In production, make sure
rm -rf public/assets
bundle exec rake assets:precompile RAILS_ENV=production
happens upon deployment.
For what it's worth, when I did this I found that no folder should be include in the path in the css file. For instance if I have app/assets/images/example.png, and I put this in my css file...
div.example { background: url('example.png'); }
... then somehow it magically works. I figured this out by running the rake assets:precompile task, which just sucks everything out of all your load paths and dumps it in a junk drawer folder: public/assets. That's ironic, IMO...
In any case this means you don't need to put any folder paths, everything in your assets folders will all end up living in one huge directory. How this system resolves file name conflicts is unclear, you may need to be careful about that.
Kind of frustrating there aren't better docs out there for this big of a change.
In rails 4 you can now use a css and sass helper image-url:
div.logo {background-image: image-url("logo.png");}
If your background images aren't showing up consider looking at how you're referencing them in your stylesheets.
when referencing images in CSS or in an IMG tag, use image-name.jpg
while the image is really located under ./assets/images/image-name.jpg
http://railscasts.com/episodes/279-understanding-the-asset-pipeline
This railscast (Rails Tutorial video on asset pipeline) helps a lot to explain the paths in assets pipeline as well. I found it pretty useful, and actually watched it a few times.
The solution I chose is #Lee McAlilly's above, but this railscast helped me to understand why it works. Hope it helps!
The asset pipeline in rails offers a method for this exact thing.
You simply add image_path('image filename') to your css or scss file and rails takes care of everything. For example:
.logo{ background:url(image_path('admin/logo.png'));
(note that it works just like in a .erb view, and you don't use "/assets" or "/assets/images" in the path)
Rails also offers other helper methods, and there's another answer here: How do I use reference images in Sass when using Rails 3.1?

Should I disable mod_rails for images and stylesheets directories?

I had a rare error in my Rails application. A CSS file was referring to non existing image files. And missing PNG file was somehow mapped to a controller action. Fortunately the action wasn't changing DB. This seems to be not OK that missing PNG can trigger controller action.
So should I disable mod_rails for static asset directories? However I've never heard this is required for Rails apps.
It is definitely a good idea, since if you allow any kind of image upload the target destination is usually the asset directory. Normally the user can quite easily upload a php or ruby file instead, so disabling all mod_evil_script for these directories is a good idea in general.
You should be serving static assets directly via Apache anyway, because it's faster. Let Rails do what it's designed to do which is handle dynamic requests.

Resources