I have a controller that when creating and editing redirects to the show page. I'm using nested atrribututes and I can not use the redirect to the path of the show. My controller is this:
class SalesmenController < ApplicationController
def show
authorize! :read, @salesman
end
def create
@salesman = Salesman.new(params_salesman)
authorize! :create, @salesman
if @salesman.save
redirect_to company_salesman_path(@salesman.id)
flash[:notice] = "Salesman saved!"
else
flash.now[:error] = "Could not create salesman!"
render :new
end
end
private
def params_salesman
params.require(:salesman).permit(:name, :company_id)
end
end
My routes are:
Rails.application.routes.draw do
resources :companies do
resources :salesmen
resources :goals do
resources :days
end
end
devise_for :owners, :controllers => { registrations: 'registrations' }
end
I am doing a test with rspec and I get the following error message:
1) SalesmenController POST #create redirect to new team
Failure/Error: redirect_to company_salesman_path(@salesman.id)
ActionController::UrlGenerationError:
No route matches {:action=>"show", :company_id=>#<Salesman id: 310, name: "Raymond Kihn", company_id: 831, created_at: "2017-10-29 03:20:33", updated_at: "2017-10-29 03:20:33">, :controller=>"salesmen"} missing required keys: [:id]
My test is this:
require 'rails_helper'
RSpec.describe SalesmenController, type: :controller do
include Devise::Test::ControllerHelpers
before(:each) do
@request.env["devise.mapping"] = Devise.mappings[:owner]
@current_owner = FactoryGirl.create(:owner)
sign_in @current_owner
@current_company = FactoryGirl.create(:company, owner: @current_owner)
end
describe "POST #create" do
before(:each) do
salesman = FactoryGirl.create(:salesman, company: @current_company)
post :create, params: {:company_id => @current_company.id, salesman: { name: salesman.name, company_id: @current_company.id } }
end
it "redirect to new team" do
expect(response).to have_http_status(:success)
end
it "Create team with right attributes" do
expect(Salesman.last.company).to eql(@current_company)
expect(Salesman.last.name).to eql(@salesman[:name])
end
end
end
Could anyone help?
You need to return the redirect, not the flash message. In Ruby, the last line to execute in the method is what gets returned. You had a flash message and thus what returned fro the create action was not a redirect call.
Fix it and you should be good!
class SalesmenController < ApplicationController
# def index...
def create
@salesman = Salesman.new(params_salesman)
authorize! :create, @salesman
if @salesman.save
flash[:notice] = "Salesman saved!"
redirect_to company_salesman_path(current_company, @salesman) # This has to executed last for the redirect
else
flash.now[:error] = "Could not create salesman!"
render :new
end
# ....
end
end
The specs need to be updated to reflect the redirection. Success is for rendering pages.
it "redirect to new team" do
expect(response).to redirect_to(company_salesman_path(company, salesman))
end
BTW you don't need to create the record in FG. You can do attributes_for(:salesman)
which you can directly use in the post.
Happy hacking!