How to link to a Rails asset without fingerprint? - ruby-on-rails

In Rails, my assets have fingerprints added to them, e.g.
mysite.com/assets/something/base-216123123asdfasd20a.css
Unfortunately, if I want to link to this from another site (like a blog) I can't rely on the fingerprint.
Is there a configuration setting I can set so that I can access files without knowing their fingerprint? (While still keeping the fingerprint for normal Rails usage; this would just be used for special cases)
I don't want to do one-off things like creating a route for a specific asset, because I'll need it for many assets.

The simplest way is to put the files directly into the public folder:
- public
-- your_file.js
This would then have to be called by referencing your URL directly = http://domain.com/your_file.js
This is only really advisable for files which you want to remain static (such as widget JS or similar).
Non Digest Assets
Alternatively, you may wish to try a gem I've never used before called non-stupid-digest-assets - a gem which allows you to determine which files are "fingerprinted" and which are not.
I've never used this gem, so cannot comment on its effectiveness, but it looks like it will give you the ability to save certain assets without their fingerprinted name. This means that you'll still be able to call them using the various asset path helpers which are available in Rails, as well as giving others a direct reference for the file:
#config/initializers/non_digest_assets.rb
NonStupidDigestAssets.whitelist = ["your_file.js"]
You'll then be able to call asset_path("your_file.js")

Related

Difference between Public and View of ruby on rails

What are the exact difference between the functionalities of app/View part and Public part of ruby on rails.
It seems that similar type of assets like js functions etc are defined in both.
what are the reasons behind defining the same things twice
In the public directory, Rails stores only static assets, i.e. files which are sent to the client as is without any further processing. These files can be generated using the assets pipeline (e.g. javascript assets or CSS files). However, they are only generated once (typically) during deployment.
The views however are the templates used by rails to generate the response to a dynamic request. Thus, if a user requests a certain (dynamic) action from your application, your controller decides which view to render. Its output is then sent to the browser. The view can thus be highly dynamic so that their output can change for each request.

Am I handling the 'public' directory the right way?

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/'

Rails: What's the advantage/disadvantage of putting scripts and stylesheets directly in public folder?

So that I could take advantage of all the already well developed front-end tools like requirejs, bower and grunt... It's just that so many of them somehow get crippled going with rails.
Primary advantages:
It is easier to load third party scripts this way. It is always possible and sometimes easy to put these through the asset pipeline, but it is also often tedious and you lose bower.
Scripts in public will not be digested, so they can be loaded by non-rails pages easily. For example, you use a javascript file on your site, and also need to load it on another, e.g., PHP site, or need to allow other people to load your script for an embedded API, etc... then you'll need to serve from public.
Primary disadvantages:
Because you're not using the asset pipeline you lose:
Asset combining and compression. Asset pipeline CSS and Javascript will be loaded in a single HTTP request each, and the content can be minified. This makes first page load on your site faster, especially if you have lots of client code or a site that needs to be super snappy for occasional visitors.
Digesting. The asset pipeline protects you 100% from cache vagaries and potentially having different users seeing your site with different version of your assets. Once you deploy, every visitor will get the new assets.
Relatively automatic etagging. Once those visitors get the new assets, their clients will generally cache them for a long time. Rails can afford to let assets cache essentially forever because digesting ensures you're not punished for this later.
So there are pros and const both ways and neither is right or wrong.
It's just that so many of them somehow get crippled going with rails
Pipeline
The reason is you're not meant to use the likes of Grunt etc with Rails. Rails' asset pipeline is only meant to contain the files which can be precompiled & used directly in your application:
The asset pipeline provides a framework to concatenate and minify or
compress JavaScript and CSS assets. It also adds the ability to write
these assets in other languages and pre-processors such as
CoffeeScript, Sass and ERB.
This will typically mean compiled third party JS/CSS files, and your own application JS/CSS files. I don't see how something like Grunt would provide any benefit to this? All it does it create a way for you to manage dependencies, versioning & source of particular assets?
--
Public
Using the files in your public folder isn't such a big deal. One of the most prominent things it does do is to exclude those particular files from the file digest processs, allowing you to use the likes of endpoints (scripts) which can be accessed by other services (outside the scope of routes.rb)
A good example of this is when we created an analytics system, and put the analytics.js into the public folder, so all the widgets could access it. This allowed other sites to access this file, regardless of the state of the asset pre-compilation.
One caveat to this would be you could perhaps have some way to store a "pseudo" file in the public folder, with it routing dynamically (with ERB) to the precompiled equivalent, but I've got no experience with this
--
Pipeline
The benefits of keeping your assets inside the asset pipeline, as stated by gwcoffey, are:
They will be compiled as you design (I.E primarily into application.js, but also into any other files you define too)
You don't need to worry about versioning (every precompile is basically a way to better the version without worrying about grunt etc)
You can include as many dependencies as you want - meaning you're able to create a totally modular set of assets which can be used throughout your app; rather than single scripts which will have their own dependency base
Recommendation
Unless you maintain third-party scripts which need dependencies to run, I would not recommend using Grunt for Rails. If you develop your own JQuery / Javascript scripts, by all means run them through Grunt etc; but for use in your app, I'd steer clear
Hope that helps!

Overriding backend assets in production environment

I am working on a project that needs to alter Refinery's WYMEditor behavior a bit. This is easily done by overriding jquery.refinery.wymeditor.js using rake refinery:override and editing it to my own needs, which works fine in development environment.
However, when it comes to production, overrides are ignored. That is, the compiled asset just contains jquery.refinery.wymeditor.js from bundle, and editing that file directly there may give the desired effect, but that's just not the way it should be done.
Strange thing is, that the problem apparently manifests itself only when trying to override backend-related assets.
It might be useful to know that I am using refinery-edge.
Any help appreciated.
So I have managed to beat it. First thing to mention is that it wouldn't be possible without poking into Refinery source code.
As I have already written in the comment, the problem was that I was trying to override an asset (wymeditor/jquery.refinery.wymeditor.js in my case) that wasn't included in a view directly, but was referenced in another asset, which was taken from the gem. And since sprockets knows nothing about Refinery's overrides, it took the referenced assets by the relative path, i.e. from the gem (and hence, unmodified), too. So, again, in my case the solution was to override the refinery/wymeditor.js, and everything worked as a charm.
Should you need to change any other backend script than WYMEditor, you will most likely have to override the refinery/refinery.js, which includes all other backend scripts, in addition to the very script you need to modify.
There is one big concern, though. With all these overrides, I have made any updates very error-prone, since some files will update, and some will not. It could have been avoided by overriding everything, but that effectively means no updates at all.
Try changing the name of the generated file and including that in your manifest instead of the original name. I suspect that it is preferring the original in the presence of two assets named the same thing.

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