Why does Rails duplicate assets when using yield? - ruby-on-rails

I've read and tried the solutions here (Ruby On Rails 3.1 - assets pipeline - assets rendered twice) for the duplicate assets problem in Rails, but it's not working on my scenario, which looks like this:
Layout:
<!DOCTYPE html>
<html>
<head>...</head>
<body>
...
<!-- including :application -->
<%= javascript_include_tag :application %>
<!-- yielding :body_script -->
<%= yield :body_script %>
</body>
</html>
Then, in a "users" view:
<%= content_for :body_script do %>
<%= javascript_include_tag 'users' %>
<% end %>
...
...
...
My javascript dependencies are that:
application.js "requires" jquery, bootstrap and self
users.js "requires" worker_interface.js
worker_interface.js "requires" jquery, knockout and application
When the "users" view is rendered, I'm getting duplicate jquery and application.js on the end of my body, one of each being rendered because of the javascript_include_tag :application and the other because of yield :body_script, like this:
<!-- including :application -->
<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/bootstrap.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<!-- yielding :body_script -->
<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/knockout.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<script src="/assets/worker_interface.js?body=1" type="text/javascript"></script>
<script src="/assets/users.js?body=1" type="text/javascript"></script>
I know that I have redundant dependencies here, because I am asking to include jquery and application more than once (indirectly). However, shouldn't Rails guarantee that no duplicate files are rendered? Can I still keep the "redundant" dependencies and have the files rendered only once?
BTW, I'm using Rails version 3.2.9.

shouldn't Rails guarantee that no duplicate files are rendered? Can I
still keep the "redundant" dependencies and have the files rendered
only once?
simple answer: no
assets are precompiled and so "static" in production. you may include assets in several ways. so there is no way for rails to "know" what files should be eliminated in the context of your rendered page.
YOU need to make sure there are not duplicates.

Related

AngularJS with Rails asset pipeline

I cannot get Angular to work with Rails asset pipeline. I have:
application.js
//= require angular
angular.module('myApp', [])
.config([function() {
console.log('In config.');
}]);
application.html.erb
<!DOCTYPE html>
<html>
<head>
<%= javascript_include_tag 'application' %>
</head>
<body ng-app="myApp"></body>
</html>
When I load the page I do not see the expected "In config" in the console. Where are no errors prompted, the source is loaded correctly. After refreshing the page two times, on the third load the console message does appear eventually.
If I replace <%= javascript_include_tag 'application' %> with simply <script src="/assets/application.js"></script>, the application does work as expected.
What am I missing here?

How do I prevent Rails from loading assets?

An understandably weird question. I'm porting a project to RoR, in order to use some of its components. Asset management is not one of them.
I wind up with something like this in my page source:
<!DOCTYPE html>
<html>
<head>
<title>Opera</title>
<link data-turbolinks-track="true" href="/assets/application.css?body=1" media="all" rel="stylesheet" />
<link data-turbolinks-track="true" href="/assets/main.css?body=1" media="all" rel="stylesheet" />
<script data-turbolinks-track="true" src="/assets/jquery.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery_ujs.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/turbolinks.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/main.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/application.js?body=1"></script>
<meta content="authenticity_token" name="csrf-param" />
<meta content="5YFRzv/wICYBms8cregzthpFqCr5gf3pQknNpLOOeEg=" name="csrf-token" />
</head>
<body>
<!-- My scripts and stylesheets below -->
What do I do differently such that the page doesn't load its own scripts and stylesheets?
Additionally, if I link stylesheets in the .erb template, they all wind up under the <body> tag. The Rails stylesheet/script helpers assume that your stuff is in the /asset directory.
How do I get Rails to link my scripts under <head> if I've placed my scripts and stylesheets in /public?
Thanks!
The default scripts and stylesheets are loaded because of the following two lines in app/views/layouts/application.html.erb
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
Rails uses the layout defined in the file app/views/layouts/application.html.erb as a default for rendering any view. The views go in the body part of application.html.erb while rendering.
You can remove the unwanted js from app/assets/javascripts/application.js file and css from app/assets/stylesheets/application.css file. You can also specify your own assets in these two files.
I am not sure about /public level. Rails pipeline assets can be placed inside an application in one of three locations: app/assets, lib/assets or vendor/assets.
Read more details for: Rails Asset Pipeline

How can I optimize javascript assets?

I've already finished my project, and it seems working fine.
But, I've just found that there's more things to do with optimization.
Google's PageSpeed Insight just told me that
I have to Remove Render-Blocking JavaScripts, Optimize CSS Delivery and Leverage Browser Caching
About Remove Render-Blocking JavaScripts, and Leverage Browser Caching, it says that I have to work with my Assets Javascripts.
They are currently stated just like this in view
<%= javascript_include_tag 'application.js' %>
<%= javascript_include_tag 'illuminate.js' %>
<%= javascript_include_tag 'bootstrapSwitch.js' %>
<%= javascript_include_tag 'bootstrap.js.coffee' %>
<%= javascript_include_tag 'rails.js' %>
and its html ouput is this
<script src="/assets/application-21cb698a1b325807d74e3f5588e.js" type="text/javascript"></script>
<script src="/assets/illuminate-1a2b0535b4a3f7468aec74882e25f3.js" type="text/javascript"></script>
<script src="/assets/bootstrapSwitch-ae37e5eb28f943501b59b08ac6234.js" type="text/javascript"></script>
<script src="/assets/bootstrap-1b52926900736585a26c3fe0975f73.js" type="text/javascript"></script>
<script src="/assets/rails-e46b066113d4a1ff96120b8493021d9.js" type="text/javascript"></script>
How can I change this to change this in order to archive?
and about Optimize CSS Delivery, it says that I have to optimize these
<%= stylesheet_link_tag "application","http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/smoothness/jquery-ui.css" %>
<%= stylesheet_link_tag 'bootstrapSwitch' %>
and this is its html ouput
<link href="/assets/application-e8a61afef574ba15cb71a3730d2b6b8e.css" media="screen" rel="stylesheet" type="text/css" />
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/smoothness/jquery-ui.css" media="screen" rel="stylesheet" type="text/css" />
<link href="/assets/bootstrapSwitch-b3ea2e51b3529f79637f5a8a9ef54712.css" media="screen" rel="stylesheet" type="text/css" />
How can I modify all of these?
Try :
1) minifying your javascripts : smaller the size, the faster will your pages load
2) using a CDN to host your assets : this helps to load your assets faster and hence a better response time
3) #depa gave some nice pointers to asset pipelines in rails, check that out as well
and you'll be good.

Ruby on Rails: How can I add a css file with rails project?

The application.html.erb file:
<!DOCTYPE html>
<html>
<head>
<title>Site</title>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
I have a file "cake.generic.css" in public/ folder.
But when I reload the page the effect of css file is not working.
If I see the page view source I see something like this:
<!DOCTYPE html>
<html>
<head>
<title>Site</title>
<link href="/assets/all.css" media="screen" rel="stylesheet" type="text/css" />
<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
<script src="/assets/home.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<meta content="authenticity_token" name="csrf-param" />
<meta content="6CPvchXr1amagxd7VmOzB82WGx/WmjfDOXjMLfjLzqQ=" name="csrf-token" />
</head>
<body>
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
</body>
</html>
What should I do to fix this problem?
How can I set the public folder for stylesheets and javascripts?
It looks that app/assets folder is set for css and js files?
Rails is likely consolidating all your css files into one that it is calling assets/all.css
Consider using the free plug-ins firebug + firepath to further characterize the problem. This common combo of tools will help you to interrogate web page elements and see the css that is contributing to their display.
Copy cake.generic.css to the folder public/assets/, if not exists make directory first.
then add this to you erb
<%= stylesheet_link_tag "cake.generic" %>
2nd question: How can i set the public folder for stylesheets and javascripts ?
Just put all you images, js and css file under 'public/assets/' and then include them in the erb pages
3rd question: It looks that app/assets folder is set for css and js files ?
Yes, 'app/assets/stylesheets/' for css and scss file
and 'app/assets/javascripts' for js and coffeescript file
You can get more info here: http://guides.rubyonrails.org/asset_pipeline.html#how-to-use-the-asset-pipeline
Hope this work for you:)
Your Style sheet should be placed in the following directory \public\stylesheets from your root project and also if you want to specify different location provide an absolute path inside stylesheet_link_tag("/public/yourfolder/test.css")
I had similar issue, but my fix was to make sure the css is under app/assets/stylesheets/ and I had to add the below line to the application.css file (my css file is named custom.css)
#import 'custom'

How can I change the indenting of AssetTagHelper so that everything lines up?

I'm fairly new to Ruby on Rails and am quite impressed with the capabilities built-in. At some point while looking at the HTML that my Rails app was generating it occurred to me that some of the indenting wasn't perfect. Seeing as Ruby is so visually appealing, why shouldn't I expect the markup it creates to be?
So, I've got the following:
<%= javascript_include_tag :defaults %>
which generates the following:
<script src="/javascripts/prototype.js?1295468839" type="text/javascript"></script>
<script src="/javascripts/effects.js?1295468839" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1295468839" type="text/javascript"></script>
<script src="/javascripts/controls.js?1295468839" type="text/javascript"></script>
<script src="/javascripts/rails.js?1295468839" type="text/javascript"></script>
<script src="/javascripts/application.js?1295468839" type="text/javascript"></script>
Notice the first line has the appropriate indentation of two spaces while each subsequent line is placed at the very beginning.
I know that I'm being a bit picky but it's 2011. Our markup should be as pretty as our UI.
Is there a way to set a new-line "delimiter" or otherwise tell rails to indent when using the AssetTagHelper?
There's no option to do this for javascript_include_tag. It just joins all the sources with newlines.
You could manually emit each script tag with something like:
<%= javascript_include_tag "prototype" %>
<%= javascript_include_tag "effects" %>
<%= javascript_include_tag "dragdrop" %>
<%= javascript_include_tag "controls" %>
<%= javascript_include_tag "rails" %>
<%= javascript_include_tag "application" %>
Another option (and a better one IMO), is to use an asset packager like Jammit - http://documentcloud.github.com/jammit/ to concatenate and minify the JS into a single file.

Resources