Marty Marty - 4 years ago 81
Ruby Question

Why is this view template expected?

I have a controller method to authenticate a user who has received a link with a token (see method at the bottom). I have an integration test:

def test
get login_path('invalid token') // Login_path routes to the controller method below.
assert flash[:danger]
assert_redirected_to root_path

This test produces the following error (referring to
get login_path('invalid token')

ActionView::MissingTemplate: Missing template invitations/login, application/login with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}.

The view
indeed doesn't exist. However, such a view should never be needed given the controller method below (it always either redirects to the
or renders
). What could be causing this error?

The controller method:

def login
inv = Invitation.where('email = ?', params[:email])
if inv
inv.each do |person|
if person.authenticated?(:invitation, params[:id])
@organization = person.organization
unless @organization.nil?
render 'profiles/show' and return
flash[:danger] = "Error"
redirect_to root_path and return
flash[:danger] = "Invalid link"
redirect_to root_path
flash[:danger] = "Invalid link"
redirect_to root_path

P.S. The test used to pass, i.e. until I rewrote the controller method to accommodate for multiple
's (see Retrieve multiple records with find_by method).

Answer Source

You use if inv - this will still return true if no invitations with matching email exist, since inv is an ActiveRecord query object. But then the each does nothing, i.e. does not redirect or render explicitly. Default render will be invoked and expect a template to exist.

Using if inv.present? will fix this.

(Also, you might want to make sure the inv collection only contains one result. Redirecting or rendering multiple times in the same request will result in an error.)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download