Javascript files in Rails 3.1 Asset Pipeline - javascript

I've tested my Rails app's functionality by placing jQuery at the bottom of my home.html.erb file with simple script tags. Everything works fine until I attempt to utilize the Asset Pipleine in Rails 3.1 and place the script within app/javascripts/home.js.erb
Anyone know why I can't get the javascript to work outside of the home.html.erb file

you could add the script tag in the application.html.erb and you'll have jquery in all your pages.
you can add the script in this way: (you should add the jquery-1.7.min file in the folder app/javascript)
<%= javascript_include_tag 'jquery-1.7.min'%>

Don't put home.js.erb in app/javascripts but extract your jquery from home.js.erb and put in app/assets/javascripts/home.js
add config.assets.precompile += %w( *.js ) to config/environments/production.rb or in config/application.rb for global env (test/dev/prod)
than in app/assets/javascripts/application.js have
//= require jquery
//= require jquery_ujs
//= require_self
//= require_tree .
call it with javascript_include_tag "application" from the view
... and finally, don't forget to add gem 'jquery-rails' to your Gemfile and run bundle

As far as what I was looking to do, which was separate javascript files for different views, I was unsuccessful. I tried different naming conventions, etc.
What has worked for me however, is putting all of my javascript within application.js. Doing this makes this code accessible by every view throughout the entire application. Depending upon your needs and your app, you may want to put the script within [your-model-name].js.coffee which will make it accessible (I think just for your particular controllers and views). Since my app is a single model/controller setup, this is essentially the same thing.
Then, it's a matter of using selectors carefully as to not interfere with other pages unintentionally. In other words, if you want a piece of code to run within one particular view and not another, you will have to adjust your .js code accordingly, since everything within application.js is accessible to all views.

Related

Why do we have to require the JS files inside application.js in rails?

I am new to rails so pardon the question. Now, why do we have to require the JS files inside the application.js file or the css files inside the application.css file? As far as I have read that when we launch the server rails loads all the javascript and css files from the directory into one file, so if it already loads all the files from the directory why there is a need to write inside the application.js or application.css file?
For example:
//= require abc
//= require xyz
If I already have abc.js and xyz.js file, why should I require them inside application.js file?
You are misunderstanding the concept. Let me explain the process. As you know, when you launch the server, rails first precompiles the files inside the assets folder with the help of sprockets-rails gem, but it does so by following the directives specified inside the manifest files i.e application.js and application.css.
Now inside the application.js you have "//= require_tree .", this tells sprockets to load all the files inside the javascript directory, process them, compress and combine them to produce one master Javascript file, this helps to reduce the page load time of the website. Now,here is your question, since "//= require_tree ." directive already takes all the javascript files present inside the javascript directory, why there is a need to specify the javascript files inside application.js? The answer is "Order".
"//= require_tree ." it loads, compress and combine all the JS files in an unspecified order or random order. Now, if you are a web developer or have started now, you might know or will come to know that many times you have to load JS files in some specific order, otherwise there may arise some conflict when we implement them, they might not work as we want them to.
One such famous combo is jquery and bootstrap. In order to use bootstrap JS part it needs jQuery, so you have to initialise jquery first and then bootstrap. Precisely for this reason in rails you require the files inside application.js specifying the order in which you want the sprockets to load,compress and combine into one master JS file. As sprockets processess the directives from top to bottom in the order specified in the application.js file, it becomes important to require the files in application.js file. If you have 2 javascript or css files which in no way connflict with each other then, there is no need for you to require the files inside application.js or application.css file and they will still work fine.
For example:
//= require jquery
//= require jquery_ujs
//= require bootstrap.min
//= require_tree .
Above, the sprockets-rails gem will first load jquery.js file then jquery_ujs.js file and then bootstrap.min.js file in that order. There is no need to add the extension as it assumes that all the files will be of type javascript only.
The above whole explanation also applies for the precompilation of css files specified inside application.css.
For more information, I advise you to visit http://guides.rubyonrails.org/asset_pipeline.html and read about rails asset pipeline.

How are Sprockets directives read in manifest file when using Rails?

New to Rails so bear with me...I was looking at a manifest file (application.js) today while researching the asset pipeline and was curious how the directives such as //= require jquery are being read. Is this something Sprockets is doing in the background? How? Why must the directive be commented out first, and the equal sign added? If I uncomment the directives and load the application.js file in my broswer, I no longer see the jquery library contents. Just curious how this is working in the background.
Also, when I add my own custom css stylesheet, do I add a require directive in the application.css manifest file, or do I add the stylesheet link such as <link rel="stylesheet" type="text/css" href="mystyle.css">? Or do I do both? I'm assuming I shouldn't add css directly inside of the manifest file...
Thanks!
Dont know how much you know, so will try to explain in details.
Rails stores our assets (like images, css, js files) in separate places, so its all in order and better for us - devs, to use. So thats called Assed Pipeline. When Rails loads those assets, say, css files, it creates one big file from all our app files, to avoid multiple calls. And Manifest is like a map or rules for Rails which files to include in that big css file and this *= is whats telling Rails what exactly to include (I consider it as a Rails syntax). So when you have something like this:
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .
require_tree . tells Rails to grab all files from the javascripts folder, while //= require jqueryand others directs Rails to special cases - assets, usually used by your gems (those files you never keep in your javascripts/stylesheets folders, so //= require_tree . cant see them).
When you add your on css file, you just add it in the stylesheets folder and require_tree informs Rails to include it in the big picture. But Rails has a nice feature - scaffolding. You scaffold your object with command rails g scaffold User and Rails creates everything for you - views, controller, model, tests (and who knows what else :) ). So in this case you don't even need to create your css file, just insert css rules into it and Rails will find it due require_tree .
A bit different story with sass files:
If you want to use multiple Sass files, you should generally use the
Sass #import rule instead of these Sprockets directives. When using
Sprockets directives, Sass files exist within their own scope, making
variables or mixins only available within the document they were
defined in.
So if you will be using Bootstrap (probably will), this is a important to know as well.
Hope this helps
How? Why must the directive be commented out first
Because this is sprockets directive. It is executed well before any js/coffee in that file gets the chance to run. And css is not "runnable" code at all. How do you make this kind of code not produce any errors? You comment it.
... and the equal sign added?
To tell these special directives apart from other, "regular" comments, which may be in that file.
I'm assuming I shouldn't add css directly inside of the manifest file...
Why not, go ahead. Although you may want to put any custom code in separate files for reasons of code organization. But technically, there's no problem here.
Also, when I add my own custom css stylesheet, do I add a require directive in the application.css manifest file
No need, require_tree . will find and include your file.
or do I add the stylesheet link such as <link rel="stylesheet"type="text/css" href="mystyle.css">?
Nope, don't do that.

Properly requiring three.js in Rails

I tried searching for a solution for this, but unfortunately nothing useful I could find came back.
I'm currently building a new Ruby on Rails application and attempting to include three.js to start practicing using it. In order to test if it was successfully required I'm using my browser console, but receiving the error:
ReferenceError: THREE is not defined
From what I saw on this question: Most efficient way to get a Three.js project to work in a ruby on rails app?
I should be receiving a return value.
I've tried both adding the three.js file in the assets/javascripts folder and using the threejs-rails gem here: https://github.com/marvindanig/threejs-rails with no success.
I've made sure to require it in the asset pipeline in the application.js file:
//
//= require three
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .
Does anyone have recommendations on what I should try next? My main issue right now appears that it's not being required correctly.
EDITED: Problem was solved. Turns out I was inheriting from the wrong controller model.
Take the Three.js file and drop it in your assets/javascript folder.
In your application.js make sure you have at the end "//= require_tree ." and it should be working fine. You should remove the "//= require three" line because rails loads it automatically and you shouldn't load anything before jquery and turbolinks or else things won't load correctly. If you want to add it to your project explicitly, add it at the end just before "//=require_tree ."
a.) Include your three.js file in
"app/assets/javascripts/three.js"
b.) in application.js file write #= require three
Make Sure server should be running. refresh the web page and type in web console(F12): Three, If it gives return result. it's done.

Application.js more than 1 Mb rails

I have a rails application and the application.js after asset compilation takes more than 1 MB. This is slowing down my entire site.
I use Apache, Rails 4, jQuery, quite heavy JavaScript and AJAX. I would be very grateful if someone could point me in the right direction.
This may not be feasible in your particular case, but has certainly helped me keep Application.js from bloating.
As I'm sure you know, Application.js compiles all specified files (by default, all of them) into a single .js file, which is loaded (again, by default) as part of your layout in every page. Often times this results in the inclusion of entirely unnecessary custom scripts loading in every page, and slowing down the entire application. I personally find this behavior undesirable. What I find works for my sites is only including my "core" javascript components in Application.js (jquery, bootstrap's js libraries, and any scripts that pertain to layout.html.erb itself), and specifying the rest in the pages that need them. For example:
application.js
Note that it does NOT include require tree .. This is important, as that is the line which specifies the inclusion of the entire assets/javascripts folder. "Template" in this case is the .js file a defined which pertains to layout.html.erb
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require bootstrap-sprockets
//= require template
//= require turbolinks
layout.html.erb
The following is the very end of my layout, immediately before the closing body tag. This loads application.js on every page, and after that loads any js specified in the view.
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<% if content_for?(:javascript) %>
<%= yield :javascript%>
<% end %>
The View(s)
In any view that requires page-specific javascript, you may specify the files with a Rails javascript helper
<% content_for :javascript do %>
<%= javascript_include_tag 'pages/profile', 'data-turbolinks-track' => true %>
<% end %>
initializers/assets.rb
Finally, make sure that your scripts are still being precompiled, even though they aren't a part of Application.js.
Rails.application.config.assets.precompile += %w( pages/profile.js )
...or, more efficiently assuming you have many pages with their own scripts...
Rails.application.config.assets.precompile += %w( pages/* )
In Conclusion
I find this technique really helps keep the size of Application.js down, and makes for good practice in general. I hope you find it useful, and apologize if it is extraneous to your problem.
Have you ever thought about using the CDN hosted jQuery Version? Could you provide your uncompiled application.js.
You could also try to use browserify or require.js

Load order with javascript_include_tag :all

So I've recently started to include quite a few .js files in to my web application and some of them depend on each other so load order is important.
However rails caching just seems to load a all.js file with no particular order to the files.
What's a good way to solve this issue?
You can do as follows
First, load the default JavaScript files.
Then load other scripts in the order that you want
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag "script_1", "script_2", "script_3" %>
The load order depends on your Javascript manifest file. In Rails 3.1 you can go to
app/assets/javascripts/application.js
At the bottom of the file you will see directives for rails how what / how to include files into the Rake pipeline. In the below example, I included a new directive that will include all the files in the directory called "Templates". I also made sure that the Handlebars.js templating file is called before all of the files in the "Templates" directory, otherwise the browser would throw an exception
//= require handlebars
//= require_tree ../templates
//= require_tree .
Hope it helps!
I've been experimenting with the YUILoader Module, it seems pretty nifty, though I am currently frussing about loading up custom modules. It's totally doable, I just couldn't figure it out in 5 mins.
http://developer.yahoo.com/yui/yuiloader/ (YUI2.8.1)
http://developer.yahoo.com/yui/examples/yuiloader/index.html

Categories

Resources