🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Q&A

解決済

1回答

1121閲覧

expected `Product.count` to have changed by 1, but was changed by 0 エラーを解消したい

mofuko

総合スコア13

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

0グッド

0クリップ

投稿2020/12/15 06:45

編集2021/02/02 08:05

前提・実現したいこと

Rails6でアプリ開発をしております。
ActiveStorageを使用した画像の複数投稿を実装し、request specを実行後に以下のエラーメッセージが発生しました。
※1つのモデルレコードに対し、1つの画像ファイルを添付させたい(画像を1枚ずつ管理したい)ため、
has_one_attached :image をモデルに設定しています。

発生している問題・エラーメッセージ

expected `Product.count` to have changed by 1, but was changed by 0

該当のソースコード

models/product.rb

# frozen_string_literal: true class Product < ApplicationRecord belongs_to :user has_one_attached :image validates :image, :title, presence: true def self.create_products_by(product_params) #そもそも一枚も上がってきてない時のためのvalidate return false if product_params[:image].nil? #途中でエラー時にRollbackするようにTransaction Product.transaction do #アップロードされた画像を一枚ずつ処理 product_params[:image].each do |product| new_product = Product.new(title: product_params[:title], image: product) return false unless new_product.save! end end true end end

products_controller.rb

# frozen_string_literal: true class ProductsController < ApplicationController def new @product = Product.new end def create @product = Product.new(product_params)#formatの部分で使うインスタンス変数用 if Product.create_products_by(product_params) redirect_to products_path else render :new end end private def product_params params.require(:product).permit(:title, { image: [] }) end

products/_form.html.erb

<div class="product_field"> <%= form.label :image %> <%= form.file_field :image, multiple: true %> </div>

spec/requests/products_spec.rb

ruby

1# frozen_string_literal: true 2 3require 'rails_helper' 4 5RSpec.describe 'Products', type: :request do 6 describe 'POST /products' do 7 subject { post products_path, params: params } 8 let(:params) do 9 { 10 product: { 11 image: image, 12 title: title 13 } 14 } 15 end 16 17 context 'when valid' do 18 let(:image) { fixture_file_upload('/files/test.jpg') } 19 let(:title) { 'success' } 20 it do 21 expect { subject }.to change { Product.count }.by(1) 22 expect(response).to have_http_status(302) 23 end 24 end 25 end 26end

spec/factories/products.rb

# frozen_string_literal: true FactoryBot.define do factory :product do user title { 'sample' } image { fixture_file_upload(Rails.root.join('spec/fixtures/files//files/test.jpg')) } end end

確認したこと

  • test.log
Started POST "/products" for 127.0.0.1 at 2020-12-15 10:30:06 +0900 Processing by ProductsController#create as HTML Parameters: {"product"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x00007fed23019088 @tempfile=#<Tempfile:/var/folders/d7/3hnp1gb57z372fh_86l8r6jc0000gn/T/RackMultipart20201215-12171-inz8o7.jpg>, @original_filename="test.jpg", @content_type="", @headers="Content-Disposition: form-data; name=\"product[image]\"; filename=\"test.jpg\"\r\nContent-Type: \r\nContent-Length: 9254\r\n">, "title"=>"success"}} [31mUnpermitted parameter: :image[0m [31mUnpermitted parameter: :image[0m Rendering products/new.html.erb within layouts/application Rendered products/_form.html.erb (Duration: 1.0ms | Allocations: 651) Rendered products/new.html.erb within layouts/application (Duration: 1.1ms | Allocations: 704) [Webpacker] Everything's up-to-date. Nothing to do Completed 200 OK in 4ms (Views: 3.7ms | ActiveRecord: 0.0ms | Allocations: 3145)

productの保存に必要なデータはパラメータに入っているが、保存されず、新規投稿画面に遷移してしまう。

  • develop環境で写真を投稿してみた結果、データベース内にも写真のレコードが保存できていることを確認
  • test環境のDBは正常に動作している

これらの他に原因を特定するために確認することなど、アドバイスいただけると幸いです。
よろしくお願い致します。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ruby

1 def product_params 2 params.require(:product).permit(:title, { image: [] }) 3 end

image: [] は配列を受け入れます。
テストで送られてきてるimageが配列ではないので

Unpermitted parameter: :image

テストのimageを以下のように[]で囲んでみてください。

ruby

1 let(:params) do 2 { 3 product: { 4 image: [image], 5 title: title 6 } 7 } 8 end

投稿2020/12/15 07:25

neko_daisuki

総合スコア2090

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mofuko

2021/02/02 08:05 編集

ありがとうございます! 確認してみます????‍♀️
mofuko

2020/12/15 07:31

テストが通りました!! ありがとうございます????
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問