Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/67.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.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 ActionController::RSpec中带有后期创建操作的UrlGenerationError_Ruby On Rails_Ruby_Rspec - Fatal编程技术网

Ruby on rails ActionController::RSpec中带有后期创建操作的UrlGenerationError

Ruby on rails ActionController::RSpec中带有后期创建操作的UrlGenerationError,ruby-on-rails,ruby,rspec,Ruby On Rails,Ruby,Rspec,我正在写一个电子商务网站,我的一个测试遇到了问题。我对创建操作的测试如下所示: require 'rails_helper' RSpec.describe ReviewsController, type: :controller do describe "POST #create" do before(:each) do user = FactoryGirl.create(:user) login user

我正在写一个电子商务网站,我的一个测试遇到了问题。我对创建操作的测试如下所示:

require 'rails_helper'

RSpec.describe ReviewsController, type: :controller do
    describe "POST #create" do
        before(:each) do
            user = FactoryGirl.create(:user)
            login user
            @product = FactoryGirl.create(:product)
            post :create, params: { blurb: "Lorem ipsum something or other" }
        end

        it "renders the product path" do
            expect(response).to redirect_to(product_path(@product))
        end
    end
end
                  Prefix Verb   URI Pattern                                 Controller#Action
                root GET    /                                           landings#index
    new_user_session GET    /users/sign_in(.:format)                    devise/sessions#new
        user_session POST   /users/sign_in(.:format)                    devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format)                   devise/sessions#destroy
   new_user_password GET    /users/password/new(.:format)               devise/passwords#new
  edit_user_password GET    /users/password/edit(.:format)              devise/passwords#edit
       user_password PATCH  /users/password(.:format)                   devise/passwords#update
                     PUT    /users/password(.:format)                   devise/passwords#update
                     POST   /users/password(.:format)                   devise/passwords#create
cancel_user_registration GET    /users/cancel(.:format)                     devise/registrations#cancel
new_user_registration GET    /users/sign_up(.:format)                    devise/registrations#new
edit_user_registration GET    /users/edit(.:format)                       devise/registrations#edit
user_registration PATCH  /users(.:format)                            devise/registrations#update
                     PUT    /users(.:format)                            devise/registrations#update
                     DELETE /users(.:format)                            devise/registrations#destroy
                     POST   /users(.:format)                            devise/registrations#create
     product_reviews POST   /products/:product_id/reviews(.:format)     reviews#create
  new_product_review GET    /products/:product_id/reviews/new(.:format) reviews#new
             product GET    /products/:id(.:format)                     products#show
             jewelry GET    /jewelry(.:format)                          products#jewelry
            clothing GET    /clothing(.:format)                         products#clothing
         decorations GET    /decorations(.:format)                      products#decorations
登录用户行可以工作,我用byebug确认存在有效的用户和会话。在这个迭代中,我得到一个错误,没有路由匹配{:action=>create,:blurb=>Lorem ipsum something或other,:controller=>reviews} ,即使我的rake路线如下所示:

require 'rails_helper'

RSpec.describe ReviewsController, type: :controller do
    describe "POST #create" do
        before(:each) do
            user = FactoryGirl.create(:user)
            login user
            @product = FactoryGirl.create(:product)
            post :create, params: { blurb: "Lorem ipsum something or other" }
        end

        it "renders the product path" do
            expect(response).to redirect_to(product_path(@product))
        end
    end
end
                  Prefix Verb   URI Pattern                                 Controller#Action
                root GET    /                                           landings#index
    new_user_session GET    /users/sign_in(.:format)                    devise/sessions#new
        user_session POST   /users/sign_in(.:format)                    devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format)                   devise/sessions#destroy
   new_user_password GET    /users/password/new(.:format)               devise/passwords#new
  edit_user_password GET    /users/password/edit(.:format)              devise/passwords#edit
       user_password PATCH  /users/password(.:format)                   devise/passwords#update
                     PUT    /users/password(.:format)                   devise/passwords#update
                     POST   /users/password(.:format)                   devise/passwords#create
cancel_user_registration GET    /users/cancel(.:format)                     devise/registrations#cancel
new_user_registration GET    /users/sign_up(.:format)                    devise/registrations#new
edit_user_registration GET    /users/edit(.:format)                       devise/registrations#edit
user_registration PATCH  /users(.:format)                            devise/registrations#update
                     PUT    /users(.:format)                            devise/registrations#update
                     DELETE /users(.:format)                            devise/registrations#destroy
                     POST   /users(.:format)                            devise/registrations#create
     product_reviews POST   /products/:product_id/reviews(.:format)     reviews#create
  new_product_review GET    /products/:product_id/reviews/new(.:format) reviews#new
             product GET    /products/:id(.:format)                     products#show
             jewelry GET    /jewelry(.:format)                          products#jewelry
            clothing GET    /clothing(.:format)                         products#clothing
         decorations GET    /decorations(.:format)                      products#decorations
当我将post行更改为如下所示: post:create,user:user,params:{blurb:Lorem ipsum something or other} 我获取的密钥不存在:user。这是我的模型:

class Review < ApplicationRecord
    belongs_to :user
    belongs_to :product

    validates_presence_of :blurb
end
我正在使用Ruby 2.4.0和Rails 5.1,如有任何帮助,将不胜感激

//编辑

我将FactoryGirl::Syntax::方法添加到我的RSpec配置中,并进行重构以使用let和product_id,如下所示:

require 'rails_helper'

RSpec.describe ReviewsController, type: :controller do
    let(:user) { create(:user) }
    let(:product) { create(:product) }

    describe "GET #new" do
        before(:each) do
            get :new, params: { product_id: product.id }
        end

        it "renders the new template" do
            expect(response).to render_template(:new)
        end

        it "returns a 200 status code" do
            expect(response).to have_http_status(200)
        end
    end

    describe "POST #create" do
        before do
            login user
        end

        context "with valid attributes" do
            let(:action) do
                post :create, product_id: product, params: { review: FactoryGirl.attributes_for(:review) }
            end

            it "creates a review" do 
                expect { action }.to change(product.reviews, :count).by(+1)
            end

            it "redirects to the review" do
                action
                expect(response).to redirect_to product.reviews.last
            end
        end
    end
end

我没有收到错误未知关键字:product\u id。我已在控制器参数中将其列为白名单,不确定从这里转到何处。

基于您的操作路线/products/:product\u id/reviews.:您需要传递product\u id的格式

因此,请将规格更改为:

post :create, product_id: @product.id, params: { blurb: "Lorem ipsum something or other" }
您可能需要在ReviewController中将actions:new更改为actions:create

您还可以将config.include FactoryGirl::Syntax::Methods行添加到rails\u helper.rb中,这样您就不必每次调用FG方法时都编写FactoryGirl:

RSpec.configure do |config|
  ...
  config.include FactoryGirl::Syntax::Methods
  ...
end

以下是基于您的行动路线/产品的

:产品id/评论:您需要传递产品id的格式

因此,请将规格更改为:

post :create, product_id: @product.id, params: { blurb: "Lorem ipsum something or other" }
您可能需要在ReviewController中将actions:new更改为actions:create

您还可以将config.include FactoryGirl::Syntax::Methods行添加到rails\u helper.rb中,这样您就不必每次调用FG方法时都编写FactoryGirl:

RSpec.configure do |config|
  ...
  config.include FactoryGirl::Syntax::Methods
  ...
end
以下是

您的路线需要产品id参数。除此之外,你的测试非常需要适当的结构。如果想查看如何测试标准crud控制器的示例,可以在rails中使用scaffold命令

require 'rails_helper'

RSpec.describe ReviewsController, type: :controller do

  # use let to setup given variables
  let(:user) {  FactoryGirl.create(:user) }
  let(:product) {  FactoryGirl.create(:product) }

  describe "POST #create" do
    before do
      login user
    end

    context "with valid attributes" do
      let(:action) do
        post :create, params: { product_id: product, review: FactoryGirl.attributes_for(:review) }
      end

      it "creates a review" do 
        expect { action }.to change(product.reviews, :count).by(+1)
      end

      it "redirects to the review" do
        action
        expect(response).to redirect_to product.reviews.last
      end
    end

    context "with invalid attributes" do
      # ...
    end
  end
end
您应该将身份验证移到一个before过滤器,并减少重复,这样您就可以将控制器压缩到相当低的程度:

# call this whatever you want but DRY it out.
class ApplicationController < InheritedResources::Base
  before_action :authenticate!

  def authenticate!
    redirect_to new_user_session_path and return false unless user_signed_in?
  end 
end 

class ReviewsController < ApplicationController
  respond_to :html
  actions :new

  def create
    @product = Product.find(params[:product_id])
    @review = @product.reviews.new(review_params) do |r|
      r.user = current_user
    end
    # don't use .save! here - it will raise an exception
    # if the record is not valid
    if @review.save
      redirect_to product_path(@product)
    else
      render :new
    end
  end

  private

  def review_params
    # only permit the params that actually should be assigned to the model!
    params.require(:review).permit(:blurb) 
  end
end
您的路线需要产品标识参数。除此之外,你的测试非常需要适当的结构。如果想查看如何测试标准crud控制器的示例,可以在rails中使用scaffold命令

require 'rails_helper'

RSpec.describe ReviewsController, type: :controller do

  # use let to setup given variables
  let(:user) {  FactoryGirl.create(:user) }
  let(:product) {  FactoryGirl.create(:product) }

  describe "POST #create" do
    before do
      login user
    end

    context "with valid attributes" do
      let(:action) do
        post :create, params: { product_id: product, review: FactoryGirl.attributes_for(:review) }
      end

      it "creates a review" do 
        expect { action }.to change(product.reviews, :count).by(+1)
      end

      it "redirects to the review" do
        action
        expect(response).to redirect_to product.reviews.last
      end
    end

    context "with invalid attributes" do
      # ...
    end
  end
end
您应该将身份验证移到一个before过滤器,并减少重复,这样您就可以将控制器压缩到相当低的程度:

# call this whatever you want but DRY it out.
class ApplicationController < InheritedResources::Base
  before_action :authenticate!

  def authenticate!
    redirect_to new_user_session_path and return false unless user_signed_in?
  end 
end 

class ReviewsController < ApplicationController
  respond_to :html
  actions :new

  def create
    @product = Product.find(params[:product_id])
    @review = @product.reviews.new(review_params) do |r|
      r.user = current_user
    end
    # don't use .save! here - it will raise an exception
    # if the record is not valid
    if @review.save
      redirect_to product_path(@product)
    else
      render :new
    end
  end

  private

  def review_params
    # only permit the params that actually should be assigned to the model!
    params.require(:review).permit(:blurb) 
  end
end

属于:产品在您的模型中,而不是控制器中!说得好!幸运的是,这是我的复制粘贴错误;您还需要使用before_action回调进行身份验证,而不是在控制器上复制相同的逻辑。before_to:产品在您的模型中,而不是控制器中!说得好!幸运的是,这是我的复制粘贴错误;您还需要使用before_action回调进行身份验证,而不是在所有控制器上复制相同的逻辑。添加product_id属性会产生以下错误:未知关键字:product_id。我将确保它在控制器中被列入白名单,并对此进行处理。添加product_id属性会产生以下错误错误:未知关键字:product_id。我将确保它在控制器中被列入白名单,并对此进行处理。感谢语法提示,我对此表示感谢。添加product_id属性会产生以下错误:unknown关键字:product_id.Ah right-在rails 5中,需要将其放入params中。编辑。我把它放在评论参数中,但没有骰子。不,你需要在规范中的参数键中传递它。帖子:创建,参数:{product\u id:product….您似乎也对强参数的作用感到困惑。它基本上可以让您过滤出应该分配给模型的参数的白名单。其余的被丢弃。这不是因为指定了客户端可以发送的每个参数。感谢语法提示,我很感激。添加product\u id属性产生以下错误:未知关键字:product_id.Ah right-在rails 5中,您需要将其放入params.edited中。我将其放入reviews_params中,但没有骰子。不,您需要在规范中的params键中传递它。post:create,params:{product_id:product….您似乎也对强参数的作用感到困惑。它基本上可以让您过滤出一个应分配给模型的参数白名单。其余的参数将被丢弃。这不是为了指定允许客户端发送的每个参数。