iamreff
iamreff

Reputation: 15

Route failing using STI

First SO post, but I've read so many. I'm new to Rails and building first site since studying Hartl's RailsTutorial.

My issue is routing using STI. I believe the routes are set up correctly, but the subclass Kid doesn't find a "show" route.

Class inheritance using STI

class User < ActiveRecord::Base

class Kid < User

Kid Controller

def show

@kid = Kid.find(params[:id])

end

User Controller create

def create
@user = User.new(params[:user])
if @user.save
  flash[:success] = "Welcome to kidtunes!"
  if (@user.type = "Kid")
    ***redirect_to @kid***
  else
redirect_to @parent
  end
else
  render 'new'
end

routes.rb

resources :users, :kids, :parents

root to: 'static_pages#home'

match '/help', to: 'static_pages#help'

match '/contact', to: 'static_pages#contact'

match '/signup', to: 'users#new'

Results in:

kids_new    GET    /kids/new(.:format)         kids#new
  users     GET    /users(.:format)            users#index
            POST   /users(.:format)            users#create
   new_user GET    /users/new(.:format)        users#new
  edit_user GET    /users/:id/edit(.:format)   users#edit
   user     GET    /users/:id(.:format)        users#show
            PUT    /users/:id(.:format)        users#update
            DELETE /users/:id(.:format)        users#destroy
   kids     GET    /kids(.:format)             kids#index
            POST   /kids(.:format)             kids#create
new_kid     GET    /kids/new(.:format)         kids#new
   edit_kid GET    /kids/:id/edit(.:format)    kids#edit
    kid     GET    /kids/:id(.:format)         kids#show
            PUT    /kids/:id(.:format)         kids#update
            DELETE /kids/:id(.:format)         kids#destroy
parents     GET    /parents(.:format)          parents#index
            POST   /parents(.:format)          parents#create
 new_parent GET    /parents/new(.:format)      parents#new
edit_parent GET    /parents/:id/edit(.:format) parents#edit
 parent     GET    /parents/:id(.:format)      parents#show
            PUT    /parents/:id(.:format)      parents#update
            DELETE /parents/:id(.:format)      parents#destroy
   root            /                           static_pages#home
   help            /help(.:format)             static_pages#help
contact            /contact(.:format)          static_pages#contact
 signup            /signup(.:format)           users#new

Error I get the following on redirect_to @kid

ActionController::ActionControllerError (Cannot redirect to nil!): app/controllers/users_controller.rb:16:in `create'

I feel like I've checked everything I can check, but I'm still missing something. @kid should properly redirect to the kids#show route. I'm not sure if I have a poorly crafted single table inheritance or a basic routing issue.

thanks in advance. -John

Form

This form is used in users/new.html.erb and it creates the User.

<div class="row">
<div class="span5 offset2">
<%= form_for(@user) do |f| %>
<%= render 'shared/error_messages' %>

<%= f.label :fname, "First Name" %>
<%= f.text_field :fname %>

<%= f.label :lname, "Last Name" %>
<%= f.text_field :lname %>

<%= f.label :email %>
<%= f.text_field :email %>

<%= f.label :type, "Are you a Kid or Parent?" %>
<%= f.select :type, [['Kid','Kid'],['Parent','Parent']] %>

<%= f.label :password %>
<%= f.password_field :password %>

<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation %>

<%= f.submit "Create my account", class: "btn btn-large btn-primary" %>
<% end %>

Upvotes: 0

Views: 340

Answers (2)

jefflunt
jefflunt

Reputation: 33954

Have you defined/assigned values to the @kid or @parent variables? If not, they will be nil, and you'll get the cannot redirect to nil error you've included in your question.

Please include the full code for the create action. Otherwise we're left to trust (rather than read for ourselves) precisely what's happening in the redirect.

Your redirects might also need some work. For example, you could do:

if (@user.is_a? Kid)
  redirect_to kid_path(@user)
else
  redirect_to parent_path(@user)
end

...or something very similar to that.

Upvotes: 1

Robin
Robin

Reputation: 21894

First thing I noticed is that you're using = instead of ==:

if (@user.type = "Kid")

I think it's nicer to test it like that:

if @user.is_a? Kid

Can you show us how you set @kid and @parent?

Upvotes: 1

Related Questions