railsのrspecでのエラーを解決したい

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 223

shinn_sora

score 7

やりたいこと
・rspecででいる下記のエラーを解決したい

  1) ProductsController POST #create saves the new product in the database
     Failure/Error: params.require(:product).permit(:name, :description, :first_category_id, :second_category_id, :third_category_id, :size, :product_status, :delivery_fee, :prefecture_id, :lead_time, :price, :transaction_status, product_images_attributes: [:image]).merge(user_id: current_user.id)

     ActionController::ParameterMissing:
       param is missing or the value is empty: product
     # ./app/controllers/products_controller.rb:49:in `product_parameter'
     # ./app/controllers/products_controller.rb:28:in `create'
     # ./spec/controllers/products_controller_spec.rb:47:in `block (3 levels) in <top (required)>'

  2) ProductsController POST #create redirects to products#index
     Failure/Error: params.require(:product).permit(:name, :description, :first_category_id, :second_category_id, :third_category_id, :size, :product_status, :delivery_fee, :prefecture_id, :lead_time, :price, :transaction_status, product_images_attributes: [:image]).merge(user_id: current_user.id)

     ActionController::ParameterMissing:
       param is missing or the value is empty: product
     # ./app/controllers/products_controller.rb:49:in `product_parameter'
     # ./app/controllers/products_controller.rb:28:in `create'
     # ./spec/controllers/products_controller_spec.rb:47:in `block (3 levels) in <top (required)>'

見た感じパラメーターに関するエラーのようなのですがどのように直せばいいか見当がつきません、、、、、、、

テストのコードは以下の通りです。

require 'rails_helper'

describe ProductsController, type: :controller do
  let(:product) {create(:product)}
  let(:user) {product.user}
  let(:category) {product.third_category}

  describe 'GET #index' do
    before do
      get :index
    end
    it "renders the :index template" do
      expect(response).to render_template :index
    end
    it "assigns the requested categories to @categories" do
      create_list(:category, 7)
      expect(assigns(:categories).size).to eq 3
    end
    it "assigns the requested categories to @brands" do
       create_list(:brand, 7)
       expect(assigns(:brands).size).to eq 4
    end
  end

  describe 'GET #new' do
    before do
      login user
      get :new
    end
    it "renders the :new template" do
      expect(response).to render_template :new
    end
    it "assigns @product" do
      expect(assigns(:product)).to be_a_new Product
    end
  end

  describe 'POST #create' do
    let(:user) {create(:user)}
    let(:params){{user_id: user.id, product: attributes_for(:product)}}
    subject {
      post:'create',
      params:params
    }
    before do
      login user
      get :create
    end
    it 'saves the new product in the database' do
      expect(subject).to change(Product, :count).by(1)
    end
    it 'redirects to products#index' do
      expect(repsonse).to redirect_to products_path
    end
  end

    describe 'GET #show' do
      context "test the template and an intance variable holding one record" do

        before do
           get :show, params: {id: product}
        end

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

        it "assigns the requested product to @product" do
          expect(assigns(:product)).to eq product
        end
      end

    context "test @images" do
      it "only assigns the images of the product with params[:id]" do
        product2 = create(:product)
        create_list(:product_image, 2, product: product2)
        images = create_list(:product_image, 2, product: product)
        get :show, params: {id: product}
        expect(assigns(:images)).to eq images
      end

      it "can only have up to 4 images" do
        images = create_list(:product_image, 7, product: product)
        get :show, params: {id: product}
        expect(assigns(:images).size).to eq 4
      end
    end

    context "test @products" do
      it "does not include the record with the same id as params[:id]" do
        get :show, params: {id: product}
        expect(assigns(:products)).not_to include(product)
      end

      it "can only have up to 6 records" do
        create_list(:product, 7, user: user)
        get :show, params: {id: product}
        expect(assigns(:products).size).to eq 6
      end
    end

    context "test @category_products" do
      it "does not include the record with the same id as params[:id]" do
        get :show, params: {id: product}
        expect(assigns(:category_products)).not_to include product
      end

      it "can only have up to 6 records" do
        category_products = create_list(:product, 7, third_category: category)
        get :show, params: {id: product}
        expect(assigns(:category_products).size).to eq 6
      end
    end
  end
end

以下のコードはfactroybotです。

FactoryBot.define do
  factory :product do
    name                 {'アメリカンイーグルのTシャツ'}
    description          {'買ったばっかり'}
    size                 {'M'}
    product_status       {0}
    delivery_fee         {0}
    prefecture_id        {1}
    lead_time            {0}
    price                {'300'}
    transaction_status   {0}
    first_category_id       {create(:category).id}
    second_category_id       {create(:category).id}
    third_category_id       {create(:category).id}
    user
  end
end

以下のコードはproduct_controllerの記述です。

class ProductsController < ApplicationController
  before_action :authenticate_user!, only: [:new, :create]
  before_action :set_product, only: :show

  def index
    @categories = Category.limit(3)
    @brands = Brand.limit(4)
    @first_categories = Category.where(ancestry: nil)
  end

  def new
    @product = Product.new
    @product.product_images.build
  end

  def show
    @images = @product.product_images.limit(4)
    @products = ProductDecorator.decorate_collection(@product.user.products.where.not(id: params[:id]).limit(6))
    @category_products = ProductDecorator.decorate_collection(@product.third_category.third_category_products.where.not(id: params[:id]).limit(6))
    if user_signed_in?
      @like = Like.find_by(user_id: current_user.id, product_id: params[:id])
    end
    @prev_item = @product.showPrevItem if @product.checkPrevItem
    @next_item = @product.showNextItem if @product.checkNextItem
  end

  def create
    @product = Product.new(product_parameter)
    respond_to do |format|
      if @product.save
        params[:product_images][:image].each do |image|
          @product_image = @product.product_images.create(image: image, product_id: @product.id)
        end
        format.html{redirect_to root_path}
      else
        @product.product_images.build
        format.html{render action: 'new'}
      end
    end
  end

  private

  def set_product
    @product = ProductDecorator.decorate(Product.find(params[:id]))
  end

  def product_parameter
    params.require(:product).permit(:name, :description, :first_category_id, :second_category_id, :third_category_id, :size, :product_status, :delivery_fee, :prefecture_id, :lead_time, :price, :transaction_status, product_images_attributes: [:image]).merge(user_id: current_user.id)
  end
end

どなたかわかる方がいらっしゃいましたらご教授の方よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる