简体   繁体   中英

Error RSpec ActionController::UrlGenerationError with Rails

I'm getting an error when trying to test a Rails Controller with RSpec. It's a double nested route and I'm trying to figure out the right syntax but hadn't had many luck yet.

The error that I'm getting is Failure/Error: get :index, {category_id: category.to_param, id: system.to_param}

ActionController::UrlGenerationError:
 No route matches {:action=>"index", :category_id=>"220", :controller=>"reviews", :id=>"166"}
 # ./spec/controllers/reviews_controller_spec.rb:11:in `block (3 levels) in <top (required)>'

I've made the same test for the system controller which works fine. The webpage works fine as well. No errors with that (just this error with testing).

Here is what the RSpec test look like:

require 'rails_helper'

RSpec.describe ReviewsController, type: :controller do

  let (:category) { create(:category) }
  let (:system) { create(:system) }
  let (:reviews) { create_list(:review, 3, category: category, system: system) }

 describe "GET index" do
   it "assigs all reviews to an instance var called @reviews" do
    get :index, {category_id: category.to_param, id: system.to_param}
    expect(assigns(:reviews)).to eq reviews
   end

  it "assigns all the reviews to an var called @system" do
   get :index, system_id: system.to_param
   expect(assigns(:system)).to eq system
  end
 end

 describe "system scope" do
  before { create(:review) }

  it "only assigns reviews index in the current system" do
   get :index, {category_id: category.to_param, id: system.to_param}
   expect(assigns(:reviews)).to eq reviews
  end
 end
end

This is the Controller that it's testing:

class ReviewsController < ApplicationController

  def index
   @system = System.find(params[:system_id])
   @reviews = @system.reviews

  respond_to do |format|
   format.html
   format.json { render json: { system: @system, reviews: @reviews } }
  end

 end

 def show
  @system = System.find(params[:system_id])
  @review = @system.reviews
 end

end

And these are the routes:

Rails.application.routes.draw do

  root "categories#index"

  resources :categories do
    resources :systems do
      resources :reviews
    end
  end
end

Here are the models:

Category Model

class Category < ActiveRecord::Base

  validates_presence_of :name

  has_many :systems

end

System Model

class System < ActiveRecord::Base

  belongs_to :category
  has_many :reviews

  validates_presence_of :name, :category

end

Review Model

class Review < ActiveRecord::Base

  belongs_to :system

  validates_presence_of :content, :system

end

ActionController::UrlGenerationError: No route matches {:action=>"index", :category_id=>"220", :controller=>"reviews", :id=>"166"}

According to your routes, that particular index route expects category_id and system_id as keys. You need to change :id to :system_id . The below should work.

it "only assigns reviews index in the current system" do
  get :index, {category_id: category.to_param, system_id: system.to_param}
  expect(assigns(:reviews)).to eq reviews
end

Update

NoMethodError: undefined method `category=' for Review:0x005578a9e87188

There is no association between a review and a category . Edit your models to set the association accordingly.

#category.rb
class Category < ActiveRecord::Base
  validates_presence_of :name
  has_many :systems
  has_many :reviews
end

#review.rb
class Review < ActiveRecord::Base
  belongs_to :system
  belongs_to :category
  validates_presence_of :content, :system
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM