Rspec使用方法has_many throw删除对象失败,没有路由匹配{:action =>" destroy"

时间:2016-05-04 11:04:26

标签: ruby-on-rails unit-testing testing rspec rspec-rails

需要一些帮助才能通过rspec测试,我的目标是删除用has_many throw方法创建的关系。我遵循了MHartl's tutorial

relationships_controller.rb:

class RelationshipsController < InheritedResources::Base

      def create
        user = User.find(params[:followed_id])
        current_user.follow(user)
        redirect_to user
      end

      def destroy
        user = Relationship.find(params[:id]).followed
        current_user.unfollow(user)
        redirect_to user
      end
    end

relationships_controller_spec.rb:

require 'rails_helper'

describe RelationshipsController do
  let(:relationship) { create(:relationship) }
  let(:user) { create(:user) }

  before do
    sign_in :user, create(:user)
  end

  describe '#create' do
    let!(:followed) { create(:user) }
    it "should require logged-in user to create relationship" do
      expect{
        post :create, followed_id: followed.id
      }.to change(Relationship, :count).by(1)
      redirect_to root_path
    end
  end

  describe '#destroy' do
    let!(:relationship) { create(:relationship) }

    it "should require logged-in user to destroy relationship" do
      expect {
        delete :destroy, id: relationship.id
      }.to change(Relationship, :count).by(-1)
      redirect_to root_path
    end
  end
end

routes.rb:

Rails.application.routes.draw do
  devise_for :users, controllers: { sessions: "users/sessions" }
  devise_for :admin_users, ActiveAdmin::Devise.config

  ActiveAdmin.routes(self)

  mount Peek::Railtie => '/peek'

  resources :users do
    member do
      get :following, :followers
    end
  end
  resources :relationships, only: [:create, :destroy]

  root to: "records#index"
end

user.rb:

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable,
         :validatable, :confirmable, :timeoutable

  # Associations
  has_many :active_relationships, class_name:  "Relationship",
                                  foreign_key: "follower_id",
                                  dependent:   :destroy
  has_many :passive_relationships, class_name:  "Relationship",
                                  foreign_key: "followed_id",
                                  dependent:   :destroy
  has_many :following, through: :active_relationships, source: :followed
  has_many :followers, through: :passive_relationships, source: :follower

  # Follows a user.
  def follow(other_user)
    active_relationships.create(followed_id: other_user.id)
  end

  # Unfollows a user.
  def unfollow(other_user)
    active_relationships.find_by(followed_id: other_user.id).destroy
  end

  # Returns true if the current user is following the other user.
  def following?(other_user)
    following.include?(other_user)
  end
end

厂:

FactoryGirl.define do
  factory :relationship do
    follower_id 1
    followed_id 1
  end
end

故障:

1) Relationships GET /relationships works! (now write some real specs)
     Failure/Error: get relationships_path

     ActionController::RoutingError:
       No route matches [GET] "/relationships"

  2) RelationshipsController#destroy should require logged-in user to destroy relationship
     Failure/Error: active_relationships.find_by(followed_id: other_user.id).destroy

     NoMethodError:
       undefined method `id' for nil:NilClass

1 个答案:

答案 0 :(得分:1)

你的销毁路线是/relationships/:id,而且控制器会破坏这种关系,但不是传递关系:id而是你通过:followed_id,所以确实存在&#39}没有这样的路线。

因此,您可以修改路由和控制器,也可以将当前代码更改为:

delete :destroy, id: relationship.id

(根据工厂的不同,您可能会收到关于没有用户的关系的错误)