Phoenix v1.3 app not rendering view index.html in Prod - heroku

The page loads perfectly on localhost, but when trying to access it live, I get an internal server 500 error. The Heroku log output:
(Phoenix.Template.UndefinedError) Could not render "index.html" for Driverless.Web.MainplayersView, please define a matching clause for render/2 or define a template at "lib/driverless/web/templates/mainplayers". No templates were compiled for this module.
What can cause this. I'm 99% sure I have all of the correct files.
Controller
defmodule Driverless.Web.MainplayersController do
use Driverless.Web, :controller
def index(conn, _params) do
render conn, "index.html"
end
end
View
defmodule Driverless.Web.MainplayersView do
use Driverless.Web, :view
end
templates/mainplayers/index.html.eex
//Just a load of html.
Router
defmodule Driverless.Web.Router do
use Driverless.Web, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", Driverless.Web do
pipe_through :browser # Use the default browser stack
get "/", PostController, :index
resources "/posts", PostController
get "/about", AboutController, :index
get "/mainplayers", MainplayersController, :index
end
# Other scopes may use custom stacks.
# scope "/api", Driverless.Web do
# pipe_through :api
# end
end
Could it be a typo in a file name somewhere? Not sure why it works fine on local machine, but not on Heroku. Other static pages load fine.

Related

Sinatra: route doesn't route when deployed to Heroku

In my app.rb:
route '/' is routed properly, I can see all the categories on the page (so my app does have all the necessary information in TechBomagCategory table).
get '/' do
#categories = Category.all
erb :categories
end
And then
Category.all.each do |category|
get '/' + category.title do
erb :products
end
end
doesn't create necessary routes. When I go to any '/' + category.title page, 404 page occurs.
Notice that on my local machine everything works as expected, all the pages are rendered perfectly fine.
What went wrong, how should I fix it?
It figures simple
heroku restart
helps. I guess that route was nonfunctional because it was created when my categories table wasn't yet seeded.

Error handlers don't run in modular Sinatra app

I have a Sinatra application that uses the modular style. Everything works fine apart from my error handler blocks which don't get invoked. Here's the relevant code:
app.rb
require_relative './routes/base'
require_relative './routes/routing'
module Example
class App < Sinatra::Application
use Routes::Base
use Routes::Routing
end
end
base.rb
require 'sinatra/base'
module Example
module Routes
class Base < Sinatra::Application
configure do
# etc.
end
# Error pages.
error 404 do # <- Doesn't get invoked.
erb :not_found
end
error 500 do # <- Doesn't get invoked.
erb :internal_server_error
end
end
end
end
routing.rb
module Example
module Routes
class Routing < Base
get '/?' do
erb :home
end
end
end
end
Why don't my error handlers work?
Thanks in advance.
The use method is for adding middleware to an app, you can’t use it to compose an app like this.
In your example you actually have three different Sinatra applications, two of which are being run as middleware. When a Sinatra app is run as middleware then any request that matches one of its routes is handled by that app, otherwise the request is passed to the next component in the Rack stack. Error handlers will only apply if the request has been handled by the same app. The app that you have defined the error handlers in has no routes defined, so all requests will be passed on down the stack — the error handlers will never be used.
One way to organise a large app like this would be to simply use the same class and reopen it in the different files. This other question has an example that might be useful: Using Sinatra for larger projects via multiple files.

Sinatra routes not working in modular app?

I've converted a classic Sinatra application to a modular application. Now suddenly my put, patch and delete routes stopped working. get and post work fine. Is there something I need to do to get these to work in a modular app that is different from classic?
%form{action: "/addsomething", method: 'post'}
%input{type: 'hidden', name: '_method', value: 'put'}
I get a 404 now when I attempt to access one of the above mentioned routes.
require 'sinatra/base'
class MyClass < Sinatra::Base
put '/addsomething' do
'HELLO WORLD!'
end
get '/hello' do
'hello world'
end
end
The method_override setting (that allows the _method field to override the HTTP method) is false by default in modular style. You need to enable it with:
enable :method_override
You can still inherit from Sinatra::Application in the modular style to keep the default settings:
require 'sinatra/base'
class MyClass < Sinatra::Application
put '/addsomething' do
'HELLO WORLD!'
end
get '/hello' do
'hello world'
end
end

Authlogic Webapp does not work any more in selenium-Javascript tests

Testing a Ruby on Rails application, I have working tests (also asa logged in user), however as soon as I put the ":js=>true" option behind a test
it "does", :js => true do
activate_authlogic
visit '/'
end
a get the web page with an internal error back
You must activate the Authlogic::Session::Base.controller with a controller object before creating objects
How can I get this to work? How can I determine the error more closely?
By now it works for me, I think because of this dirty snippet
module Authlogic
module Session
module Activation
module ClassMethods
def controller
if !Thread.current[:authlogic_controller]
Thread.current[:authlogic_controller] = Authlogic::TestCase::MockController.new
end
Thread.current[:authlogic_controller]
end
end
end
end
end
witch comes from the question SO: authlogic-with-capybara-cucumber-selenium-driver-not-working

Sinatra: How do I provide access to a login form while preventing access to the rest of my Sinatra app?

I recently created a Sinatra app with a login form (no basic auth). To prevent access to the app unless the user logged in I put a before block in place
before do
unless request.path_info == '/login'
authenticated?
end
end
I quickly realized that this prevented me from accessing resources in the public directory like my style sheet and logo unless authenticated first as well. To get around that I changed my filter to the following:
before do
unless request.path_info == '/login' || request.path_info == "/stylesheets/master.css" || request.path_info == "/images/logo.png"
authenticated?
end
end
If there were lots of resources I needed to provide exceptions to this way of making them would quickly become overwhelming. What is a better way to code this so I can make exceptions for the public directory or even its specific sub-directories and files like /stylesheets, /images, /images/bg.png but not /secret or /secret/eyes-only.pdf?
Or ... Is there a completely different best-practice to handle this situation of locking down everything except the stuff related to logging in (handlers, views, resources)?
You could extract the login logic into it's own Rack middleware (which can be a Sinatra app).
The authentication middleware will serve the public files.
require 'sinatra'
class Authentication < Sinatra::Base
def logged_in?
# your login logic goes here
end
get '/login' do
# login formular and logic here
end
get(//) do
pass if logged_in?
redirect '/login'
end
end
configure { |c| c.use Authenitcation }
get('/') { ... }
Instead of putting the authorization information into your Sinatra application directly, why don't you extract it into Rack using Rack::Auth:
# my_app.ru
app = Rack::Builder.new do
use Rack::Static, :urls => /^(stylesheets|javascripts|images|fonts)\//
map '/login' do
run MyApplication
end
map '/' do
use Rack::Auth::Basic do |username, password|
# check the username and password sent via HTTP Basic auth
end
run MyApplication
end
end

Resources