Search code examples
ruby-on-railscapybararspec-rails

Rails URL changing without view changing


I am testing an app in Rails and having a failure I can't figure out. I have a table called "Families" with basic CRUD functionality. When creating a new "family" in the new view, if the title is not validated, the new view is supposed to be rendered again. And it is. But the URL changes from "families/new" to "families." The view and the URL do not match. And my test is failing as a result. Why is this happening in my URL? Here is my test:

require 'rails_helper'

feature "Creating a family" do 

scenario "A user creates a family with invalid title" do 
    visit '/'
    click_link 'Create Family'
    click_button "Create"
    expect(page.current_path).to eq(new_family_path)
end

end 

Here are the new and create actions in my controller:

def new 
    @family = Family.new
end 

def create 
    @family = Family.new(family_params)
    if @family.save
        redirect_to root_path
    else 
        flash.now[:danger] = "There was a problem"
        render :new
    end 
end

Family model:

class Family < ApplicationRecord

    validates :title, presence: true

end

Solution

  • Right here:

    def create 
      @family = Family.new(family_params)
      if @family.save
        redirect_to root_path
      else 
        flash.now[:danger] = "There was a problem"
        render :new
      end 
    end
    

    When you hit the create action, you are POSTing to families. You then render :new - which leaves you at the families url with the new partial showing.

    If you want to end up at the families/new url, you need to do something more like:

    def create 
      @family = Family.new(family_params)
      if @family.save
        redirect_to root_path
      else 
        flash.now[:danger] = "There was a problem"
        redirect_to new_family_path
      end 
    end
    

    Remember: rendering and routing are two separate things. Just because you render :new does not imply that you should end up at the new_families_path url. Two different things.