Random routing errors in Rails public routing - ruby-on-rails

I'm writing a jQuery Mobile website to be turned into a PhoneGap/Cordova app. To facilitate this, I created a brand new rails project, and after changing to the 'thin' gem for a webserver, put the entire jQuery Mobile app in the public/myapp folder of the new Rails project.
This all works fine; I can reach my mobile app from localhost:3000/myapp but after a few hours of testing suddenly the Rails app starts throwing 404s all over the place. What is likely to have happened?
This is ONE of the errors I see in the rails server logs:
ActionController::RoutingError (No route matches [GET] "/js/setlocation_address.js"
Basically every single reference in my <head> tag to a javascript or css file returns with a 404 error.

I think the solution was to put
config.serve_static_assets = true
in the config/environments/production.rb file but I'm not sure if this solved the issue as it was an intermittent one.
EDIT
Actually it seems the problem was that I would sometimes go to localhost:3000/myapp and sometimes to localhost:3000/myapp/index.html .
Although Rails would route me to the same index.html page each time, my browser wouldn't pickup the relative paths correctly, and would try to GET localhost:3000/css/styles.css instead of localhost:3000/myapp/css/styles.css.

Related

Specific Image Not Loading After Rails 7 ESBuilt Update

I have a very frustrating issue with a Rails 7 app after migrating to Ruby 3.2 with Esbuild.
Basically there is a few specific images that simply will not load, however, there are many others that load just fine that live in the same location, and are accessed the exact same way. It's driving me nuts.
I have cleared cached, restarted servers, cleared all the local build files, everything I can think of. This is also happening in both dev and production.
My Esbuild is running just fine, it is finding the files and compiling them with a finger print. The files all exist and are in the right location. (all sitting under app/assets/builds)
Accessing the file direcly in the browser, ie
http://localhost:4000/assets/logo_white_trans-QEBURZJB.png
Fails with a 404, cannot find the image. This file however exists with the correct name in the app/assets/builds folder.
Accessing another image from the page ie
http://localhost:4000/assets/leadstory-symbol-B5T7OIJB.png
Loads just fine.
It's almost like there is a static list of rails routes that match the images and it is not generating the route for some of these specific images, hence the 404, even though the file exists.
Some screenshots that highlight the odd behaviour
and the files listed in the directory, showing the file clearly exists
My package.json build step is
esbuild app/javascript/bundles/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=/assets --minify --log-limit=0 --loader:.js=jsx --loader:.png=file --loader:.svg=file
And a snip from the app of how its being loaded.
import LogoWhiteTrans from "../../assets/images/logo_white_trans.png";
<img src={LogoWhiteTrans} className="logo" alt="logo" />
Which looks to be working fine, the HTML outputs
<img src="/assets/logo_white_trans-QEBURZJB.png" class="logo" alt="logo">
The image can be loaded fine, from elsewhere in the app in a regular rails view using asset helpers (not from within the React app)
ie <%= asset_path('logo_white_trans.png') %>
Something I have noticed is in the logs, I see
ActionController::RoutingError (No route matches [GET] "/logo_white_trans-QEBURZJB.png"):
Notice there it does not say "/assets/logo_white_trans..."? I thought that was weird, as the URL in the image tag clearly has a /assets at the start. Trying either path does not work, with or without /assets directly in the browser. Just seems odd rails would see it that way
Im going nuts here, what am I missing. Its not a png specific issue, as other pngs are loading fine in the same way, nor is it an image issue the file exists and the naming is fine.
Is there some sort of manifest thats not being updated? An internal asset route list or something along those lines?
Im running Rails 7
Ruby 3.2
ESBuild
This isn't really an answer, but what I have ended up doing is moving all image assets out of the asset pipeline and into the public folder. I noticed that my assets were being duplicated by esbuilt and the rails asset precompile process, and basically the javascript build and rails eco system just do not work well together.
For anyone else having issues like this, we've just moved all our static assets in the public/images folder and we refernce the path /images/blah.png the same way in both React and Ruby now.
All image tags in either React or standard .erb views are just <img src="/images/blah.png/>. Its a lot cleaner.
Yes, we have given up asset finger printing, but its a small loss, considering most images never change and It's dramatically simplified things and sped up our build process considerably as it does not have to touch each file during precompilation.
Our views now also just have standard tags, instead of <asset_path> tags, which im sure is just quicker in general instead of ruby generating these asset strings all the time.
So, not really and answer to the initial question but it is a solution, and one i think anyone who is fusing modern javascript, react, typescript etc into a Rails app.

Why can't I get my RoR app to look at the compiled files in prod?

I have developed a RoR-application that runs perfectly fine in dev-environment but as soon as I upload it to Heroku it breaks. This is because my assets (Stimulus JS-controllers) are not being loaded. I have been trying to find out what is wrong and it seems to come down to the fact that my app is trying to serve my non-compiled files. I have attempted the heroku-way using config.serve_static_files = true but to no gain. I am all lost for clues at this point... Using Rails 7.
Tried to clear assets, re-compile, change paths but it does not make sense as I am expecting Rails self to try to load those pre-compiled assets with a hash on them.
This is what I see in Heroku-logs: ActionController::RoutingError (No route matches [GET] "/assets/controllers/openinghours_controller.js"):

for every request in rails, is it normal to 'get' assets in rails app?

in my sample rails app, i'm refreshing my page to see what happens.
with every refresh, i'm seeing other things like
Started GET "assets/welcome.self[...]"
Started GET "assets/application.self[...]"
... + maybe 6 other "GET xxxxxx " things along.
files are css and js.
for every view folder i have, i think it's doing this. like "assets/profiles ~~etc"
this is not a good thing, is it? all my js and css files for those are empty. I only have some code within the application.css and application.js.
In development it is pretty normal, because assets are not compiled yet and not cached by browser, and not server by webserver without hitting rails (NB: but you have to set all these up for your production deployment)
You can add gem 'quiet_assets' to your gemfile to remove assets logging to console, this can be useful.

Can I Identify The Environment Using HTML Code?

I just figured out how to create custom error pages in the public folder using I18n. Those error pages have links that will return the user to a page in the application such as the home page.
When my application was running 3.2.13 I had the custom error pages in the app folder using config.exceptions_app = self.routes in application.rb. When I had that code all I had to do was use a link_to statement pointing to the route I wanted the user to return to. If I was in the development environment it would go to http://localhost:3000/somelink and in production it would go to http://myrailsapp.com/somelink. I replaced these with the ones in the public folder after rewriting them in Rails 4 because it appears that config.exceptions_app = self.routes is ignored in Rails 4.
My error pages in the public folder are html, not html.erb so there is no ruby/rails code. I would like to replicate what I had previously where I can check the environment in my error pages and point to localhost for development or my domain URL for production. I currently have code in my error page similar to this:
My Link Text
I'm definitely open to changing these to html.erb files. I initially thought about that but from my research and trying what I found nothing is working for Rails 4.
Any help would be appreciated.
You don't need any "autodetection" in html, just cut the domain part from the url and use a local path instead.
Just change http://myrailsapp.com/en/home to /en/home.
And yes, you do need the opening slash to be independent from the current_url in your link.

Highcharts doesn't work on Heroku

I have a ruby on rails app that uses highcharts.
Locally it works like a charm, however when I push the app to Heroku, Highcharts stops working and the div tag that is supposed to contain the chart appears empty.
I even tested it with one of the Highcharts examples (which has only hardcoded data), and still nothing.
Figured it out: The problem was in the precompiling of assets. Turned out that highcharts was not precompiled
Added :
config.assets.precompile += ['rollover.js', 'highcharts.js']
to production.rb (i suppose application.rb should work as well)
and
to layout file.
(since i expected all javascript files gets compiled in application.jss i only had <%= javascript_include_tag "application" %> in my layout file)
Sounds like Highcharts is not loading - either because it isn't being pushed to Heroku or because it isn't being served properly. Go to the URL where highcharts.js should be and see if you get the JavaScript or a 404.
If you can reach highcharts.js without issue then the problem is most likely in the setup code. Check and see if the appropriate variables are loaded onto the page (using the web developer tools for the browser you are testing in) and if there are any JavaScript errors showing up when the page is loaded.
Using lazy highcharts gem. Googled for an hour Nothing worked out for me.
Finally I've copied highcharts.js from Vendor directory and pasted it to assets.
Viola!

Resources