Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rspec和FactoryGirl:堆栈级别太深错误_Ruby On Rails_Ruby_Ruby On Rails 4_Rspec_Factory Bot - Fatal编程技术网

Ruby on rails Rspec和FactoryGirl:堆栈级别太深错误

Ruby on rails Rspec和FactoryGirl:堆栈级别太深错误,ruby-on-rails,ruby,ruby-on-rails-4,rspec,factory-bot,Ruby On Rails,Ruby,Ruby On Rails 4,Rspec,Factory Bot,我是rails新手,正在为我的API将关联嵌入到我的模型中。但是,添加嵌入导致“我的规范”引发以下错误: Rails:4.2.3 Ruby:2.2.1 Rspec:3.3.2 FactoryGirl:4.5.0 1) Api::V1::ProductsController GET #show returns the information about a reporter on a hash Failure/Error: get :show, id: @product.id

我是rails新手,正在为我的API将关联嵌入到我的模型中。但是,添加嵌入导致“我的规范”引发以下错误: Rails:4.2.3 Ruby:2.2.1 Rspec:3.3.2 FactoryGirl:4.5.0

  1) Api::V1::ProductsController GET #show returns the information about a reporter on a hash
     Failure/Error: get :show, id: @product.id
     SystemStackError:
       stack level too deep
从堆栈溢出的其他答案来看,我认为我在测试中如何使用工厂存在问题

以下是模型: product.rb

class User < ActiveRecord::Base
  validates :auth_token, uniqueness: true


  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  before_create :generate_authentication_token!

  has_many :products, dependent: :destroy

  def generate_authentication_token!
    begin
      self.auth_token = Devise.friendly_token
    end while self.class.exists?(auth_token: auth_token)
  end
end
products.rb

FactoryGirl.define do
  factory :product do
    title { FFaker::Product.product_name }
    price { rand() * 100 }
    published false
    user
  end
end
这是我从中获得所有错误的规范。 产品\控制器\规格rb

require 'spec_helper'

describe Api::V1::ProductsController do

  describe "GET #show" do
    before(:each) do
      @product = FactoryGirl.create :product
      get :show, id: @product.id
    end

    it "returns the information about a reporter on a hash" do
      product_response = json_response[:product]
      expect(product_response[:user][:email]).to eql @product.user.email
    end

    it "has the user as an embeded object" do
      product_response = json_response[:product]
      expect(product_response[:user][:email]).to eql @product.user.email
    end

    it { should respond_with 200 }
  end

  describe "GET #index" do
    before(:each) do
      4.times { FactoryGirl.create :product }
      get :index
    end

    it "returns 4 records from the database" do
      products_response = json_response
      expect(products_response[:products]).to have(4).items
    end

    it "returns the user object into each product" do
      products_response = json_response[:products]
      products_response.each do |product_response|
        expect(product_response[:user]).to be_present
      end
    end


    it { should respond_with 200 }
  end

  describe "POST #create" do
    context "when is succesfully created" do
      before(:each) do
        user = FactoryGirl.create :user
        @product_attributes = FactoryGirl.attributes_for :product
        api_authorization_header user.auth_token
        post :create, { user_id: user.id, product: @product_attributes }
      end

      it "renders the json representation for the product record just created" do
        product_response = json_response[:product]
        expect(product_response[:title]).to eql @product_attributes[:title]
      end

      it { should respond_with 201 }

    end
    context "when is not created" do
      before(:each) do
        user = FactoryGirl.create :user
        @invalid_product_attributes = { title: "Smart TV", price: "Twelve dolalrs" }
        api_authorization_header user.auth_token
        post :create, { user_id: user.id, product: @invalid_product_attributes }
      end

      it "renders an errors json" do
        product_response = json_response
        expect(product_response).to have_key(:errors)
      end

      it "renders the json errors on why the product could not be created" do
        product_response = json_response
        expect(product_response[:errors][:price]).to include "is not a number"
      end

      it { should respond_with 422 }
    end

  end

  describe "PUT/PATCH #update" do
    before(:each) do
      @user = FactoryGirl.create :user
      @product = FactoryGirl.create :product, user: @user
      api_authorization_header @user.auth_token
    end

    context "when is successfully updated" do
      before(:each) do
        patch :update, { user_id: @user.id, id: @product.id,
                         product: { title: "An expensive TV"} }
      end

      it "renders the json representation for the updated user" do
        product_response = json_response[:product]
        expect(product_response[:title]).to eql "An expensive TV"
      end

      it { should respond_with 200 }
    end

    context "when is not updated" do
      before(:each) do
        patch :update, { user_id: @user.id, id: @product.id,
                         product: { price: "two hundred" } }
      end

      it "renders an errors json" do
        product_response = json_response
        expect(product_response).to have_key(:errors)
      end

      it "renders the json errors on why the user could not be created" do
        product_response = json_response
        expect(product_response[:errors][:price]).to include "is not a number"
      end

      it { should respond_with 422 }
    end
  end

  describe "DELETE #destroy" do
    before(:each) do
      @user = FactoryGirl.create :user
      @product = FactoryGirl.create :product, user: @user
      api_authorization_header @user.auth_token
      delete :destroy, { user_id: @user.id, id: @product.id }
    end

    it { should respond_with 204 }
  end

end
以及产品控制员:

class Api::V1::ProductsController < ApplicationController
  before_action :authenticate_with_token!, only: [:create, :update]
  respond_to :json

  def show
    respond_with Product.find(params[:id])
  end

  def index
    respond_with Product.all
  end

  def create
    product = current_user.products.build(product_params)
    if product.save
      render json: product, status: 201, location: [:api, product]
    else
      render json: { errors: product.errors }, status: 422
    end
  end

  def update
    product = current_user.products.find(params[:id])
    if product.update(product_params)
      render json: product, status: 200, location: [:api, product]
    else
      render json: { errors: product.errors }, status: 422
    end

  end

  def destroy
    product = current_user.products.find(params[:id])
    product.destroy
    head 204
  end

  private

    def product_params
      params.require(:product).permit(:title, :price, :published)
    end
end
class Api::V1::ProductsController
user_serializer.rb

class UserSerializer < ActiveModel::Serializer
  attributes :id, :email, :created_at, :updated_at, :auth_token
  has_many :products
end
class UserSerializer

编辑:添加产品控制器

您可以发布您的
产品控制器
?您可以在rails控制台中测试您的工厂。我会检查如何工作
generate\u authentication\u token方法,因为此方法可能导致无限循环。您的产品模型代码是否已完成?我怀疑FactoryGirl.create(:product)的“堆栈级别太深”发生在before(:each)中。当您尝试在产品的回调中创建或更新某些内容时,可能会发生这种情况,因此,这些回调会在无限循环中触发。此外,这会做什么:
在self.class.exists时结束?(auth\u token:auth\u token)
class Api::V1::ProductsController < ApplicationController
  before_action :authenticate_with_token!, only: [:create, :update]
  respond_to :json

  def show
    respond_with Product.find(params[:id])
  end

  def index
    respond_with Product.all
  end

  def create
    product = current_user.products.build(product_params)
    if product.save
      render json: product, status: 201, location: [:api, product]
    else
      render json: { errors: product.errors }, status: 422
    end
  end

  def update
    product = current_user.products.find(params[:id])
    if product.update(product_params)
      render json: product, status: 200, location: [:api, product]
    else
      render json: { errors: product.errors }, status: 422
    end

  end

  def destroy
    product = current_user.products.find(params[:id])
    product.destroy
    head 204
  end

  private

    def product_params
      params.require(:product).permit(:title, :price, :published)
    end
end
class UserSerializer < ActiveModel::Serializer
  attributes :id, :email, :created_at, :updated_at, :auth_token
  has_many :products
end