Hello everybody, I have this problem (title of the post).
Failure/Error: get :create, :user => { :email => 'foo@example.com', :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 => 'foo@example.com', :name => 'userexample' }
flash[:notice] = 'new user was successfully created.'
end
end
end
if @user.save
redirect_to :action => :show, :id => @user.id
else
...
end
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: "baylor@example.com" }
assigns(:user).email_address.should == "baylor@example.com"
end
end
end