Asantoya
Asantoya

Reputation: 247

No route matches {:action=>"show", :controller=>"user", :id=>nil}

Hello everybody, I have this problem (title of the post).

Failure/Error: get :create, :user => { :email => '[email protected]', :name => 'userexample' }
ActionController::RoutingError:No route matches {:action=>"show", :controller=>"user", :id=>nil}

Here is my UserController.

class UserController < ApplicationController

  def new
  end

  def create
    @user = User.new(params[:user])
    @user.save
    redirect_to :action => :show, :id => @user.id
  end

  def show
    @user = User.find(params[:id])
  end
end

Here is my routes.rb

::Application.routes.draw do

  devise_for :users
  root :to => "user#index"
  resources :user
  #match "newuser" => "user#new"
  get "user/new"
  post "user/create"
  get "user/:id" => "user#show"

And here is my rspec test

require 'spec/spec_helper'

describe UserController do
  it "create new user" do
    get :create, :user => { :email => '[email protected]', :name => 'userexample' }
      flash[:notice] = 'new user was successfully created.'
    end
  end
end

Upvotes: 4

Views: 5744

Answers (2)

Baylor Rae&#39;
Baylor Rae&#39;

Reputation: 4010

Most Rails apps use this type of content block for creating and updating records.

def create
  @user = User.new(params[:user])

  if @user.save
    redirect_to @user, :notice => "User was created successfully."
  else
    render :new
  end
end

Basically, when the create action is run it creates a new record, or a new instance of the User model.

When .save is called it checks all the validations. If the validations pass then it returns true, else it returns false.

If it returns false, then you need to render the :new template again so person has a chance to fix any validation errors.

If it returns true, then you want to redirect to the show action. The cool thing about rails is that it can automatically figure that out by just passing the instance @user.


Ryan Bates has a tutorial on testing controllers with RSpec. Based on what he does, this is how I would test your controller.

require 'spec/spec_helper'

describe UserController do

  describe "POST 'create'" do

    it "should redirect to user on successful save" do
      User.any_instance.stub(:valid?) { true }
      post :user
      flash[:notice].should_not be_nil
      assigns(:user).should_not be_a_new_record
      response.should redirect_to(assigns(:user))
    end

    it "should render new template on failed save" do
      User.any_instance.stub(:valid?) { false }
      post :user
      flash[:notice].should be_nil
      assigns(:user).should be_a_new_record
      response.should render_template(:new)
    end

    it "should pass params" do
      User.any_instance.stub(:valid?) { true }
      post :user, :user => { email_address: "[email protected]" }
      assigns(:user).email_address.should == "[email protected]"
    end
  end
end

Upvotes: 1

Yuri  Barbashov
Yuri Barbashov

Reputation: 5437

if @user.save
   redirect_to :action => :show, :id => @user.id
else
 ...
end

Upvotes: 5

Related Questions