嵌套路由,没有路由匹配

时间:2012-12-22 20:05:29

标签: ruby-on-rails nested-routes

我有三种资源 - userslistsitems。我刚刚在lists下嵌套users并相应地更新了我的链接,但是我从rspec得到了两个错误,这对我来说是一个完全的谜。在嵌套路线之前,一切正常。

我是铁杆的新手,因此非常感谢任何帮助!

  1) Authentication authorization for non-signed-in users in the Lists controller submitting to the destroy action 
     Failure/Error: before { delete user_list_path(user, FactoryGirl.create(:list)) }
     ActiveRecord::RecordInvalid:
       Validation failed: Email has already been taken
     # ./spec/requests/authentication_pages_spec.rb:84:in `block (6 levels) in <top (required)>'

  2) User pages profile page 
     Failure/Error: before { visit user_path(user) }
     ActionView::Template::Error:
       No route matches {:action=>"show", :controller=>"users", :id=>nil}
     # ./app/views/shared/_user_info.html.erb:1:in `_app_views_shared__user_info_html_erb__1836116684083464018_70145329446120'
     # ./app/views/users/show.html.erb:4:in `_app_views_users_show_html_erb___902249955135429148_70145329432180'
     # ./spec/requests/user_pages_spec.rb:12:in `block (3 levels) in <top (required)>'

的routes.rb

MyApp::Application.routes.draw do
  resources :users do
    resources :lists, only: [:show, :create, :destroy]
  end
  resources :items, only: [:show, :create, :destroy]
  resources :sessions, only: [:new, :create, :destroy]

user.rb

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation
  has_secure_password
  has_many :lists, dependent: :destroy
  has_many :items, through: :lists

list.rb

class List < ActiveRecord::Base
  attr_accessible :name
  belongs_to :user
  has_many :items, dependent: :destroy

item.rb的

class Item < ActiveRecord::Base
  attr_accessible :link, :list_id, :title
  belongs_to :list

更新

user_pages_spec.rb

require 'spec_helper'

describe "User pages" do

  subject { page }

  describe "profile page" do
    let(:user) { FactoryGirl.create(:user) }
    let!(:l1) { FactoryGirl.create(:list, user: user, name: "Foo") }
    let!(:l2) { FactoryGirl.create(:list, user: user, name: "Bar") }

    before { visit user_path(user) }

    it { should have_selector('h1',    text: user.name) }
    it { should have_selector('title', text: user.name) }

    describe "lists" do
      it { should have_content(l1.name) }
      it { should have_content(l2.name) }
      it { should have_content(user.lists.count) }
    end
  end

  describe "lists page" do
    let(:user) { FactoryGirl.create(:user) }
    let!(:l1) { FactoryGirl.create(:list, user: user, name: "Foo") }
    let!(:i1) { FactoryGirl.create(:item, list: l1, title: "Shirt") }

    before { visit user_list_path(user, l1) }

    it { should have_content(i1.title) }
    it { should have_content(l1.items.count) }
  end
...

更新2

users_contoller.rb

class UsersController < ApplicationController
  before_filter :signed_in_user, only: [:edit, :update]
  before_filter :correct_user,   only: [:edit, :update]

  def show
    @user = User.find(params[:id])
    @lists = @user.lists
    @list = current_user.lists.build if signed_in?
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(params[:user])
    if @user.save
      sign_in @user
      flash[:success] = "Welcome to Wishlistt!"
      redirect_to @user
    else
      render 'new'
    end
  end

  def edit
  end

  def update
    if @user.update_attributes(params[:user])
      flash[:success] = "Profile updated"
      sign_in @user
      redirect_to @user
    else
      render 'edit'
    end
  end

  private

    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_path) unless current_user?(@user)
    end
end

1 个答案:

答案 0 :(得分:1)

您的第一个错误是告诉您正在创建的用户无效,因为已经创建了具有该电子邮件的用户。 (未通过电子邮件唯一性验证)您可以通过更改用户工厂来对电子邮件进行排序,以便每条记录都是唯一的,如下所示:

sequence(:email) { |n| "User#{n}@example.com"}

第二次测试失败的原因完全相同。由于您的用户记录为零,因此您实际上是在尝试从数据库中获取不存在的记录。它在线上告诉你:

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

通过让用户= nil,您的show动作中会发生以下情况:

your implementation will look something like this:
#####
@user = User.find(params[:id])
#####

因为params [:id] = nil,你得到

User.find(nil)

由于没有id为nil的用户记录,因此会失败。其余的实现应该没问题。