【发布时间】:2017-04-17 23:27:51
【问题描述】:
我正在编写一个电子商务网站,但我的一项测试遇到了问题。我对创建操作的测试如下所示:
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
“登录用户”行有效,我通过 byebug 确认了这一点(存在有效的用户和会话)。在此迭代中,我收到 No route matches {:action=>"create", :blurb=>"Lorem ipsum something or other", :controller=>"reviews"} 的错误 ,即使我的 rake 路线看起来像这样:
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 :create, user: user, params: { blurb: "Lorem ipsum something or other" } 我得到“密钥不存在:用户”。这是我的模型:
class Review < ApplicationRecord
belongs_to :user
belongs_to :product
validates_presence_of :blurb
end
我的控制器:
class ReviewsController < InheritedResources::Base
respond_to :html
belongs_to :product
actions :new
def create
@review = Review.new(review_params)
@product = Product.find(params[:product_id])
if user_signed_in?
@review.user_id = current_user.id
@review.product_id = params[:product_id]
if @review.save!
redirect_to product_path(@product)
else
render :new
end
else
redirect_to new_user_session_path
end
end
private
def review_params
params.require(:review).permit(:blurb, :utf8, :authenticity_token, :commit)
end
end
还有我的 routes.rb:
Rails.application.routes.draw do
root 'landings#index'
devise_for :users
resources :products, only: [:show] do
resources :reviews, only: [:new, :create]
end
get '/jewelry', to: 'products#jewelry', as: :jewelry
get '/clothing', to: 'products#clothing', as: :clothing
get '/decorations', to: 'products#decorations', as: :decorations
end
我正在使用 Ruby 2.4.0 和 Rails 5.1,我们将不胜感激。
//编辑
我将 FactoryGirl::Syntax::Methods 添加到我的 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_id”。我已在控制器参数中将其列入白名单,不知道从哪里开始。
【问题讨论】:
-
belongs_to :product进入您的模型 - 而不是控制器! -
好点!幸运的是,这是我的复制粘贴错误;)
-
您还需要使用
before_action回调来进行身份验证,而不是在所有控制器上复制相同的逻辑。
标签: ruby-on-rails ruby rspec