Rails not rendering public/index.html file; blank page in browser - ruby-on-rails

I have a problem with my Rails + React app when I deploy it to Heroku. The React client is inside a client/ directory of the Rails app. Due to using react-router, the Rails server needs to know to render the index.html from the React build. When I deploy the client on Heroku, a script copies the content from client/build/. to the Rails app's public/ dir.
Now here is the problem: when my route detects a path like example.com/about it tries to render public/index.html. Here is the method:
def fallback_index_html
render file: "public/index.html"
end
However, the contents from this file are not sent to the browser. I get a blank page. I have added a puts "hit fallback_index_html" in the method and confirmed that this method is being hit. I have also opened the file in puts each line to confirm the file has the required html (this is what appeared in the logs from that puts and what SHOULD be sent to the browser):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="/manifest.json">
<link rel="shortcut icon" href="/favicon.ico">
<title>Simple Bubble</title>
<link href="/static/css/main.65027555.css" rel="stylesheet">
</head>
<body><noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="text/javascript" src="/static/js/main.21a8553c.js"></script>
</body>
</html>
The most recent fix I tried was going into config/environments/production.rb and changing config.public_file_server.enabled to true. This did not help.

I'm using Rails API, so my ApplicationController inherits from ActionController::API instead of ActionController::Base.
From Rails API docs it says:
The default API Controller stack includes all renderers, which means you can use render :json and brothers freely in your controllers. Keep in mind that templates are not going to be rendered, so you need to ensure your controller is calling either render or redirect_to in all actions, otherwise it will return 204 No Content.
Thus Rails API only cannot render HTML! The following allowed me to render the html without including everything from ActionController::Base.
class ApplicationController < ActionController::API
include ActionController::MimeResponds
def fallback_index_html
respond_to do |format|
format.html { render body: Rails.root.join('public/index.html').read }
end
end
end
The reason I am including ActionController::MimeResponds is to have access to the respond_to method.
My Rails application now renders index.html from my public directory when a subdirectory is hit and my React client / react-router takes over from there.

Related

How to send an acceptable response when trying to receive SMS with Twilio, Heroku, and Rails?

So I had (most) of the following setup working on a Twilio test number last week. I was running from localhost:300 using ngrok to receive the POST from twilio. Everything worked great: didn't need blank-response.xml.erb, just rendered :nothing => true and the message came in and was handled by the controller - simple.
Today I am trying to deploy the app on heroku (and am switching credentials to a paid account) and keep recieving the following error in the Twilio console:
12200 Schema validation warning
Cvc-elt.1: Cannot find the declaration of element 'html'.
I have tried rendering the xml response a half dozen different ways with the most textbook version outlined below. My problem is the response never changes (from what's also listed below). I don't know if I'm missing something stupid or if Heroku hates Twilio or what and I'm at a loss as to what to do at this point. Any help is welcome!
Code samples
url (Twilio webhook):
http://www.mycoolurl.com/confirmation
routes.rb:
post 'confirmation' => 'appointments#confirm'
appointments_controller:
def confirm
incoming_message_body = params["Body"]
from_number = params["From"]
if incoming_message_body.downcase.match("yes")
puts "CONFIRMED for #{from_number}"
elsif incoming_message_body.downcase.match("no")
puts "CANCELED for #{from_number}"
end
render 'blank-response.xml.erb', :content_type => 'text/xml'
end
blank-response.xml.erb
<?xml version="1.0" encoding="UTF-8"?>
<Response></Response>
Response from my Rails App:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>My Cool Website</title>
<META name="description" content="some stupid blurb about this site">
<META name="keywords" content="a bunch of cool keywords">
</head>
<frameset rows="100%,*" border="0">
<frame src="https://cool-name-24253.herokuapp.com/confirmation" frameborder="0" />
<frame frameborder="0" noresize />
</frameset>
<!-- pageok -->
<!-- 06 -->
<!-- -->
</html>

Undefined method `mime_type` in Mailer Preview when using Attachments

I've created a mailer in my Rails 4 application, which works perfectly well when there are no attachments to the emails. However, when I add a pdf attachment to the emails, I get the following error when I try to preview the email at .../rails/mailers/donor_mailer/thankyou_mail_preview
NoMethodError in Rails::Mailers#preview
Showing /usr/local/rvm/gems/ruby-2.1.5#rails4/gems/railties-4.1.6/lib/rails/templates/rails/mailers/email.html.erb where line #95 raised:
<iframe seamless name="messageBody" src="?part=<%= Rack::Utils.escape(#part.mime_type) %>"></iframe>
However, I don't get this error, or any issues at all actually, when sending the emails themselves, only with the preview. Has any one else experienced this, and know how to fix this / knows the direction I should be heading in. Could this cause any further issues down the line with my emails, or is it just a problem with the preview feature?
My Mailer is as follows:
class DonorMailer < ActionMailer::Base
default from: "user#gmail.com"
def thankyou_email(computer)
#computer = computer
#donor = computer.donor
attachments["some.pdf"] = File.read("path/to/pdf/some.pdf")
mail(to: #donor.donor_email, subject: "Thank you")
end
end
and template is:
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
<p>Email content here</p>
</body>
</html>
I tried adding :pdf to my MIME types to no avail.
Thank you

Ruby file on execution from command line in Ubuntu generates a blank file

I am trying to run a .rb file through the command line in Ubuntu. Although , the execution is not giving any errors, the file generated after the process is a blank one. I have checked all the necessary modules needed like ruby, rails etc and few documentations on the net as well.
Please help me on this.
My code Snippet is given below:
<% page_title = "Test Demo Ruby File " %>
<% salutation = "Hello," %>
<html>
<head>
<title><%= page_title %></title>
</head>
<body>
<p><%= salutation %></p>
<p>Successfully template has been loaded in erb</p>
</body>
</html>
and I am expecting something like this:
<html>
<head>
<title>Test Demo Ruby File </title>
</head>
<body>
<p>Hello,</p>
<p>Successfully template has been loaded in erb</p>
</body>
</html>
File generated? The erb myfilename.rb command displays the HTML as expected. If you want it in a file, redirect the output:
erb myfilename.rb > foo.html
foo.html will contain the generated HTML. Why are you doing this, if you are using Ruby on Rails?

Using asset pipeline outside of ERB

Is there a way to use the rails asset pipeline outside of erg? When I call stylesheet_link_tag(), I get a normal /stylesheets/ link instead of an /assets/ like I'd expect. I suspect that the stache gem just needs to register something with the asset pipeline, but I'm not sure what.
I'm using this gem: https://github.com/agoragames/stache
The code I'm using:
module Layouts
class Application < ::Stache::View
include ActionView::Helpers::AssetTagHelper::StylesheetTagHelpers
def title
'foobar'
end
def stylesheets
[
[stylesheet_link_tag('reset', :media => 'all')]
]
end
def javascripts
end
end
end
It's generating:
<link href="/stylesheets/reset.css" media="all" rel="stylesheet" type="text/css" />
It should be generating (it does this in erb templates):
<link href="/assets/reset.css?body=1" media="all" rel="stylesheet" type="text/css" />
Using rails 3.2.3.
Try
def stylesheets
[
[stylesheet_link_tag("#{ActionController::Base.helpers.asset_path('reset.css')}", :media => 'all')]
]
end
also read https://stackoverflow.com/a/9341764/643500
The proper solution is to remove the:
include ActionView::Helpers::AssetTagHelper::StylesheetTagHelpers
line at the top.

Problems Rendering View (ActionView::MissingTemplate ... Error) in Custom Plugin

I am trying to develop a plugin for Ruby on Rails and came across problems rendering my html view. My directory structure looks like so:
File Structure
---/vendor
|---/plugins
|---/todo
|---/lib
|---/app
|---/controllers
|---todos_controller.rb
|---/models
|---todos.rb
|---/views
|---index.html.erb
|---todo_lib.rb
|---/rails
|---init.rb
In /rails/init.rb
require 'todo_lib'
In /lib/app/todo_lib.rb
%w{ models controllers views }.each do |dir|
# Include the paths:
# /Users/Me/Sites/myRailsApp/vendor/plugins/todo/lib/app/models
# /Users/Me/Sites/myRailsApp/vendor/plugins/todo/lib/app/controllers
# /Users/Me/Sites/myRailsApp/vendor/plugins/todo/lib/app/views
path = File.expand_path(File.join(File.dirname(__FILE__), 'app', dir))
# We add the above path to be included when Rails boots up
$LOAD_PATH << path
ActiveSupport::Dependencies.load_paths << path
ActiveSupport::Dependencies.load_once_paths.delete(path)
end
In todo/lib/app/controllers/todos_controller.rb
class TodosController < ActionController::Base
def index
end
end
In todo/lib/app/views/index.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"[url]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd[/url]">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>Todos:</title>
</head>
<body>
<p style="color: green" id="flash_notice"><%= flash[:notice] %></p>
<h1>Listing Todos</h1>
</body>
</html>
In /myRailsApp/config/routes.rb
ActionController::Routing::Routes.draw do |map|
# The priority is based upon order of creation: first created -> highest priority.
map.resources :todos
...
The error I get is the following:
Template is missing
Missing template todos/index.erb in view path app/views
Can anyone give me a hand up and tell me what am I doing wrong here that is causing my index.html.erb file to not render? Much appreciated!
EDIT:
I have already tried the following without success:
In /todo/lib/app/controllers/todos_controller.rb
def index
respond_to do |format|
format.html # index.html.erb
end
end
EDIT:
hakunin solved this problem. Here's the solution.
He says that I'm building a Rails engine plugin (I had no idea I was doing this), and it requires a different directory structure, one that appears like so:
File Structure
---/vendor
|---/plugins
|---/todo
|---/lib
|---/app
|---/controllers
|---todos_controller.rb
|---/models
|---todos.rb
|---/views
|---/todos
|---index.html.erb
|---todo_lib.rb
|---/rails
|---init.rb
This required the following changes:
In todo/lib/todo_lib.rb
%w{ models controllers views }.each do |dir|
# Include the paths:
# /Users/Me/Sites/myRailsApp/vendor/plugins/todo/app/models
# /Users/Me/Sites/myRailsApp/vendor/plugins/todo/app/controllers
# /Users/Me/Sites/myRailsApp/vendor/plugins/todo/app/views
path = File.expand_path(File.join(File.dirname(__FILE__), '../app', dir))
# We add the above path to be included when Rails boots up
$LOAD_PATH << path
ActiveSupport::Dependencies.load_paths << path
ActiveSupport::Dependencies.load_once_paths.delete(path)
end
The change made above is in the line: path = File.expand_path(File.join(File.dirname(FILE), '../app', dir)). [Ignore the boldened 'FILE', this is an issue with the website].
Running script/server will render the index.html.erb page under todo/app/views/todos.
Looks like you want to build an "engine" plugin. Create "app" and "config" dirs in the root of your plugin dir (not under /lib). You can use app/views/ and app/controllers in your plugin as if it was a full featured Rails app. In config/routes.rb you should declare routes introduced by your engine.
See http://github.com/neerajdotname/admin_data for a decent example of what engine looks like.

Resources