ruby on rails jquery.js and application.js both fire a request per ajax button - ruby-on-rails

Firefox is firing off two requests when I click on the following button (and all other ajax forms on the page):
<%= form_tag(action_object_path, :remote => true) do -%>
<div><%= submit_tag "run process" %></div>
<% end -%>
I do not want this behavior. I pulled up firebug and can see that there are two requests made:
POST http://localhost:3000/object/1/action jquery.js?body=1 (line 8527)
POST http://localhost:3000/object/1/action application.js?body=1 (line 8527)
How do I fix this to only fire one request when I click my button?
One thing I remember that may help diagnose this problem. I know they are both javascript assets and can vaguely remember modifying something with my assets immediately after I started building my app because rails server barked at me and told me to precompile (I at least think it was precompile) my assets. I don't remember what I did and so dont' know how to reverse it.
I also read somewhere that firefox's cache may cause it to fire two requests, so I have tried clearing my cache and that does not work.
Thanks

To explain the problem a bit more clearly than the comments indicate:
The jquery-ujs javascript library adds event bindings to change events for elements that would normally generate standard HTTP requests (and are flagged as :remote) into AJAX requests. In Rails you would typically have the jquery-rails gem installed and then have the jquery_ujs.js file render in one of several ways:
add a require jquery_ujs line in your application.js manifest
add a javascript_include_tag :jquery_ujs line to your application layout file
copy the jquery_ujs file to your assets and rely on some line in the application.js manifest to pull it in (e.g. require_tree .)
Choosing more than one of these methods will cause the library to be linked twice - and will result in the symptoms described.

Related

DEPRECATION WARNING: The asset "ckeditor.js" is not present in the asset pipeline.Falling back to an asset that may be in the public folder

I recently updated to Rails 5.2.2 (from 4.2.3) and now I'm getting this warning in the logs on pages using CKEditor gem.
DEPRECATION WARNING: The asset "ckeditor.js" is not present in the asset pipeline.Falling back to an asset that may be in the public folder.
This behavior is deprecated and will be removed.
To bypass the asset pipeline and preserve this behavior,
use the skip_pipeline: true option.
This is the line:
<%= javascript_include_tag :ckeditor %>
I tried adding skip_pipeline: true but then it started making requests for "/javascripts/ckeditor.js" which gave a 404 error.
Either way, the CKEditor works and the text field is rich text. I have this line in my application.js
//= require ckeditor/init
It works even without the javascript_include_tag. I get the feeling the previous dev thought CKEditor was a large library and only wanted to include it on specific pages in the admin that needed it. How can that be achieved?
Rails is going to give you a JavaScript file per file in your JavaScript assets folder. For example, you should have a javascript_include_tag for :application because of that "application.js" file there. You’re including ckeditor into your application.js file, which is why ckeditor works. But, you’re trying to include a JavaScript file for an asset that doesn’t exist, meaning there is no "ckeditor.js" file in your javascripts folder.
This message is coming from Rails attempting to look up the asset name for the js file, because in prod Rails tacks on a unique hash to the file name to prevent caching.
This has likely been a problem the whole time, and you just never noticed the JavaScript file 404ing, and now Rails 5.2 is louder about the problem than 4.2 was.
You should just delete the javascript_include_tag line.
Alternatively you could create a ckeditor.js file, and move the //= require ckeditor/init from the application.js file over to ckeditor.js. Now you can do the javacript_include_tag only on pages that need it. But be wary of your load order. If you have any js in your application.js file that depends on ckeditor or vice versa, you’ll need to make sure you include your files in the right order in the html (the same order that the requires happened in, in application.js, assuming the order matters).
This worked
<%= javascript_include_tag 'ckeditor/init' %>
I also commented out the line in the application manifest
// only load on required pages // require ckeditor/init

Rails - rack::offline not permanently caching vendor javascript

I'm building a Rails app that needs to be able to load a particular view/action while a user is offline, using the rack::offline gem... some of the functionality of the page in question is dependent on jQuery, and I added jQuery 2.2.4 to the vendor javascript folder. jQuery 2.2.4 is required in the application.js file, but the problem that I am having is that jQuery doesn't seem to be getting added to the cache, and the jQuery functionality is lost if the user refreshes the browser while offline.
I was able to temporarily resolve this issue by literally pasting the entire jQuery script into the view in question, but that is definitely not a practical solution.
How can I make sure the jQuery file in my vendor scripts is cached along with the HTML for he view in question?
The html element for the view includes the manifest attribute...
<html manifest="/application.manifest">
and from routes.rb
get '/application.manifest' => Rails::Offline
from my application.js file
//= require jquery-2.2.4.js
//= require turbolinks
//= require_tree .
And, to be comprehensive, here's the manifest...
CACHE MANIFEST
# 70f990270c71e8065f366ef4b2d73c870e89f37e4dbef32b57e0135c84b90001
404.html
422.html
500.html
NETWORK:
*
The first time I visit the page while offline (after caching), no problem, it pulls up the working cached version. However, as I mentioned, if I refresh the page, it loses the jQuery functionality ($ is undefined, etc.), although the HTML remains unchanged.
Pleased to say that I was able to figure this out...
You'll notice in my original post, there was no jQuery being included in the manifest - this is a problem! First thing, I needed to make sure that jQuery was tucked into my public folder - I added it to public/javascripts/jquery-2.2.4.js.
Now my manifest looks like this:
CACHE MANIFEST
# 70f990270c71e8065f366ef4b2d73c870e89f37e4dbef32b57e0135c84b90001
404.html
422.html
500.html
javascripts/jquery-2.2.4.js
NETWORK:
*
Lovely!
Now, despite the fact that I had put jQuery into the public folder, it wasn't automatically loading when I navigated to the view that was being cached (I'd love it if someone could help me figure out why that is happening, but it's not the end of the world). So, I added <script> src="/javascripts/jquery-2.2.4.js"></script> to the head of the layout file associated with the view, and boom, there ya go.
Now jQuery is being cached appropriately, my app runs offline.

Turning on turbolink

After I've precompiled assets and uploaded them to CDN I decided to turn on turbolinks. They were kind of turned on before when I were precompiling assets, that is I had gem turbolinks in Gemfile and require turbolinks in application.js but in application.html I had data-no-turbolink instead of data-turbolinks-track" => true.
Now I change it to data-no-turbolink to data-turbolinks-track" => true and expect them to work in production on the my local machine but it seems they aren't. Visually it seems they aren't working and "initiator" in the browser isn't turbolinks.
I don't want to recompile the assets if it's not really needed because reuploading them to CDN takes a lot of time.
So do I have to recompile them? Or perhaps I just don't notice that they are really working already?
data-turbolinks-track is only for asset tracking (to make sure the loaded assets file is the latest). It does not affect whether Turbolinks is used for a particular link.
If turbolinks is installed, any internal link without data-no-turbolink will be loaded using Turbolinks UJS.
The following code will fire an alert if Turbolinks is running.
$(document).on('page:load', function(){ alert("Turbolinks is active"); });
Not easy with the sparse information you provide. But here are some notes worth considering:
About Turbolinks:
With Turbolinks pages will change without a full reload, so you can't
rely on DOMContentLoaded or jQuery.ready() to trigger your code.
Instead Turbolinks fires events on document to provide hooks into the
lifecycle of the page.
You probably use jQuery? Read above link to understand. A good solution is this one: jQuery.turbolinks
...
But if you have a large codebase with lots of $(el).bind(...)
Turbolinks will surprise you. Most part of your JavaScripts will stop
working in usual way. It's because the nodes on which you bind events
no longer exist.
...

No browser loading bar

I can't seem to find a similar issue
On my website I am running into an issue where the browser progress bar will not show until the page is completely rendered.
This is particularly bad on a very slow page (which I am working on). It makes it look like the link may have been broken instead of just taking a little while.
Looking at the network
There is a GET method on the current page which returns a 304, this runs for about 3-5 seconds.
Once that finishes the new website will load with a near instant progress bar.
I am not sure what code I can share since this is happening everywhere on my site, it is just more noticeable on certain pages.
To see it at its worse go to http://www.swtorconquest.com/conquestweeks and click either "The Trade Emporium" or "Clash in Hyperspace".
I am having this issue both when testing locally and when the site is deployed.
I am using ruby 2.1.2 and rails 4.1.5
Do one thing, in application.html.erb, in body tag add this, it will solve your problem
<body data-no-turbolink>
The problem will almost certainly be Turbolinks, although this is just a guess. Lacking any other answers, I'll hopefully be able to give you some ideas:
When you load a page with Turbolinks, it will actually load the <body> tag of the page through Ajax, leading the <head> intact.
This causes a lot of problems if not handled correctly, one of which (we've found) being that your browser can no longer determine how quickly the page is loading. This is likely what your problem is.
Although I don't have an outright fix, I do have a test.
You can try removing any references to Turbolinks throughout the various pages in this part of your application. This can be done by using the following:
#app/views/layouts/application.html.erb
<%= javascript_include_tag "application" %> => remove the turbolinks reference
<%= stylesheet_link_tag "application" %> => remove the turbolinks reference
Also, you need to remove Turbolinks from your Gemfile & your application.js:
#app/assets/javascripts/application.js
//= require turbolinks => remove this line
This will give you the ability to gauge whether it's turbolinks which is preventing the status bar from loading correctly. If it is, then you'll have to work around this (I don't have any remedies off hand)
It must be noted that this test will not speed up the load time - it will merely show whether the status bar issue is caused by Turbolinks or not

dropdowns only trigger once

I have two filter dropdowns on this site which will only trigger the first time I press them. According to my studies it seems that it has to do with turbolinks, which I've disabled by adding data-no-turbolink to the body tag like so:
<body data-no-turbolink>
...
</body>
I've also tried adding this to all of the dropdown links and the link to open the dropdown.
<a href="some-link" data-no-turbolink>...</a>
It seems to work on development, but when I push to Heroku, it seems turbolinks are running again. Any suggestions?
If Turbolinks is an issue, it can be removed entirely from the project by following the instructions provided e.g. here:
remove gem 'turbolinks' from the Gemfile and run bundle update
remove //= require turbolinks from app/assets/javascripts/application.js
remove "data-turbolinks-track" => true from the stylesheet and javascript tags in the header of application.html.erb layout file.
Quoting Rails 4 In Action:
...it's our opinion that Turoblinks is great to speed up
mostly-server-side sites, but as soon as you start writing some
JavaScript, it causes more problems than it's worth.

Resources