Rails is rendering a javascript .js.erb file in the view - ruby-on-rails

I have a situation in Rails 5.2 where a controller is rendering a .js.erb file to the view literally, i.e. showing the javascript code in the view itself.
How can I get Rails to run the js.erb file instead of showing it as if it were a DOM file? It is taking the user away from a page I want the user to stay on.
# controller
def submit_custom_data
...perform some functions...
respond_to do |format|
format.js
end
end
# submit_custom_data.js.erb
console.log('submit_custom_data...');
... Other javascript ...
Additional Info
By preserving the browser console logs on Chrome, I see this:
Resource interpreted as Document but transferred with MIME type text/javascript: "http://localhost:3000/submit_custom_data/1068.js?c=1&d=10&db=1&s=8&tm=&w=3".
Navigated to http://localhost:3000/submit_custom_data/1068.js?c=1&d=10&db=1&s=8&tm=&w=3
This issue did NOT occur on Rails 4.2.7. After updating to Rails 5.2.7 (and updating the bundle), I'm now seeing these issues.

Related

Rails: Use of absolute path in Rails 6

Recently, I've upgraded a Rails app that I'm maintaining to Rails 6 RC2 (coming from 5.2.3). So, right after upgrading, I ran the automated tests (RSpec) and the test output gave me lots of deprecation warnings. One of those warnings was:
DEPRECATION WARNING: render file: should be given the absolute path to a file
So I went to the view file that triggered the warning, and made the changes as follows,
Before:
render file: 'devise/sessions/new'
After:
render file: Rails.root.join('app', 'views', 'devise', 'sessions', 'new.html.slim')
I ran the tests again, no output of deprecation warnings was seen. However, after switching to absolute paths, the view is now only rendering plain HTML code but if I remove the .slim extension, i.e.
render file: Rails.root.join('app', 'views', 'devise', 'sessions', 'new.html')
The corresponding view is rendered properly but now the test will complain about not using absolute paths. Is there a way to fix this or is this a Rails/Slim bug?
In your case it looks like you want to render a normal view, i.e. a template.
In that case using the file option is not the recommended way. Instead you should be using the template option.
render template: 'devise/sessions/new'
Or even better, you can use this shortcut:
render 'devise/sessions/new'
Background
The file option is intended to render a view which is outside your Rails application, where you can't rely on Rails' view lookup logic. Consequently Rails wants to have an absolute path. Demanding an absolute path also forces the developer to think about relative path segments (/../).
Omitting the .slim extension and then having the file processed by the template engine is a feature intended for templates. Using file seems to provide the very same functionality, but my guess is that this is just a side effect of the internal workings of the view path lookup. It looks like the Rails developers want to improve the distrinction between files and templates in the future and deprecating relative files is an intermediate step to not break too many existing applications which rely on using file and still expect the features of a template.
PS: It is not necessary to manually split your path. So if you for some reason still want to use file with an absolute path, instead of
render file: Rails.root.join('app', 'views', 'devise', 'sessions', 'new.html.slim')
use this
render file: Rails.root.join('app/views/devise/sessions/new.html.slim')
I had this same challenge when working on Rails 6 API-only application.
I wanted to render a static page from a controller called home_controller.rb
Here's my code:
require 'rails/application_controller'
class HomeController < Rails::ApplicationController
def index
render file: Rails.root.join('public/index.html')
end
end
But when I try accessing the page I get the error:
Started GET "/favicon.ico" for ::1 at 2021-02-23 16:25:41 +0100
Processing by HomeController#index as */*
Parameters: {"other"=>"favicon"}
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms | Allocations: 301)
ArgumentError (`render file:` should be given the absolute path to a file. '/home/my-computer/Projects/MyWebsite/public/index.html' was given instead):
Here's how I solved it:
The issue was that I was missing the file index.html in the directory public, so Rails could not locate it.
All I had to do was to add the file index.html in the directory public. This time when I tested it was fine.
That's all.
I hope this helps

missing a template for this request format and variant

I am new to Ruby on Rails and am trying to gain a strong understanding of how MVC works.
I did the following:
rails new bubblesman
rails generate controller bubble
in my bubble controller I created a method as follows:
def available
puts "YEP!!!!!!"
end
I put the following in my routes file:
'welcome' => 'bubble#available'
I navigate to http://localhost:3000/welcome
I get the below error:
ActionController::UnknownFormat (BubbleController#available is missing a template for this request format and variant.
request.formats: ["text/html"]
request.variant: []
NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not… nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot.):
what I also don't understand is if I put this in my helper controller instead of my main controller it all works fine.
you need to create the available.html.erb file within the views/bubble/ directory. When the route takes you to that action, it also navigates you to that view, so if you put:
<h2>YEP!!!!</h2>
as the only line in that file, it should return that to you on the webpage.
In the future, you could use rails g scaffold bubbles and that will create a majority of the files (MVC) and routes for you.

Opening .html.erb files in browser

Is there a way to open .html.erb files by themselves in the browser. The Rails app I am trying to have a look at is in rails 2.3 and will not run locally on the rails server nor will it run when I give the command script/server.
I would just like to open the individual views in the browser by themselves...is this possible?
You can open them in the browser, but the <% %> and <%= %> tags will get shown as-is instead of executing the Ruby code. These are template files that need to get processed by Rails to fill in data at runtime. Your best bet is TsaiKoga's answer, making a controller action render the template in question.
In rails4 you can do it like this:
erb a.html.erb > a.html
Maybe it doesn't work in rails 2.3. If you want to render that view, maybe you can use an action just like users#index and change the code to render it:
render "devise/mailer/a.html.erb", :layout => false

Rails is Using HTML View When Requesting Javascript

Weird issue where I'm asking for the JS file, but Rails is serving the HTML file. And it's only on my staging server (Heroku) and not on my local machine.
I have a dynamic Javascript file which is something that needs to be included in other pages via a script to like so:
<script type="text/javascript" src="http://example.com/embed.js></script>
That embed maps to a controller and action which also handles HTML. The relevant route looks like this:
match "/embed(.:format)" => "articles#embed", as: "embed"
And the controller action is pretty standard.
def embed
respond_to do |format|
format.html do
#it renders some HTML
end
format.js #no block is given
end
end
And, I have two views under app/views/articles
embed.html.haml
embed.js.coffee
On my local machine, requesting localhost:3000/embed.js works. It renders the Javascript without a problem. However, on my staging server, here's what I see in the logs:
Started GET "/embed.js" for 124.168.219.36 at 2012-11-04 00:23:01 +0000
Processing by ArticlesController#embed as JS
Rendered articles/embed.html.haml (1.5ms)
Completed 500 Internal Server Error in 2ms
The Internal Server Error is not the issue. The issue is that it recognises the request as JS, yet decides to render the HTML template and only on staging.
What's going on?

Rails dynamic select menu for 3.1

How would this be updated for Rails 3.1?
http://railscasts.com/episodes/88-dynamic-select-menus
I just can't figure out how to call the js.erb file and have it run the code to generate the javascript dynamically.
Might be something: in Rails 3.1, you're most likely using jQuery instead of Prototype. The example code on the Railscasts site is using good old Prototype instead of the new hotness that is jQuery (default javascript library in Rails 3.1).
Once all your jquery pipes are connected, having rails respond to and render your js.erb is the same as always. In your controller:
def country_selected
// whatever you need to do
respond_to do |format|
format.js
end
end
Then in your view directory, you have a country_selected.js.erb that you can put in whatever javascript you want to update the second select menu. (Remember you have to escape your shiz for it to work correctly) e.g.
<%= escape_javascript(params[:country]) %>
By the way, I think .rjs was moved out of Rails proper and into it's own Gem. Something else to keep in mind regarding Rails 3.1 vs. javascript.

Resources