質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails 6

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

Ruby on Rails

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

Q&A

0回答

2413閲覧

accepts_nested_attributes_for がモデルにあるときのRspecを通したい

mikannOishiii

総合スコア6

Ruby on Rails 6

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

Ruby on Rails

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

0グッド

0クリップ

投稿2020/06/16 02:25

編集2022/01/12 10:55

前提・実現したいこと

accepts_nested_attributes_for を使って親子関係にある2つのモデルがある。
(親:Post, 子:Picture)
request_spec で create する際、Post も Picture も数が増えるというテストを書いて通したい。
なお、テストの書き方はこちらのQiitaの記事を参考にしました。

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

terminal

1I, [2020-06-16T04:23:23.051589 #976] INFO -- : Parameters: {"post"=>{"title"=>"MyTitle", "content"=>"MyContent", "pictures_attributes"=>[{"name"=>[#<ActionDispatch::Http::UploadedFile:0x0000558e67b27a78 @tempfile=#<Tempfile:/tmp/RackMultipart20200616-976-olzaw.png>, @original_filename="testfile.png", @content_type="spec/support/testfile.png", @headers="Content-Disposition: form-data; name=\"post[pictures_attributes][][name][]\"; filename=\"testfile.png\"\r\nContent-Type: spec/support/testfile.png\r\nContent-Length: 15605\r\n">]}]}} 2D, [2020-06-16T04:23:23.070685 #976] DEBUG -- : Unpermitted parameter: :name

name カラムに許可されていないパラメータを含んでいるからエラーという意味???

該当のソースコード

Model

rb

1# app/models/post.rb 2class Post < ApplicationRecord 3 has_many :pictures, dependent: :destroy 4 accepts_nested_attributes_for :pictures, allow_destroy: true 5end

rb

1# app/models/picture.rb 2class Picture < ApplicationRecord 3 belongs_to :post 4 mount_uploader :name, PictureUploader 5 validates :name, presence: true 6end

Post (記事)は複数の Picture を持つことができる。
また、 Post が削除されるとそれに紐づく Picture も削除される。

コントローラー

rb

1# app/controllers/admins/posts_controller.rb 2class Admins::PostsController < ApplicationController 3 before_action :admin_user 4 PICTURE_COUNT = 3 5 6 def index 7 @posts = Post.all 8 end 9 10 def new 11 @post = current_admin.posts.build 12 PICTURE_COUNT.times { @post.pictures.build } 13 end 14 15 def create 16 @post = current_admin.posts.build(post_params) 17 if @post.save 18 flash[:notice] = "記事を投稿しました!" 19 redirect_to admins_dashboard_url 20 else 21 render action: :new 22 end 23 end 24 25 # --- 省略 --- 26 27 private 28 29 def post_params 30 params.require(:post).permit(:title, :content, :status, pictures_attributes: [:name]) 31 end 32end

current_admin は、 current_user と同じと考えてもらって良いです。

FactoryBot

# spec/factories/posts.rb FactoryBot.define do factory :post do title { "MyTitle" } content { "MyContent" } association :admin end end

rb

1# spec/factories/pictures.rb 2FactoryBot.define do 3 factory :picture do 4 name { [Rack::Test::UploadedFile.new(Rails.root.join('spec/support/testfile.png'), 'spec/support/testfile.png')] } 5 association :post 6 end 7end

RSpec(失敗)

rb

1# spec/requests/admins/posts_request_spec.rb 2 3context "with valid params" do 4 it "投稿・画像が登録されること" do 5 params = { pictures_attributes: [ attributes_for(:picture) ] } 6 expect do 7 post admins_posts_url, params: { post: attributes_for(:post).merge(params) } 8 end.to change(Post, :count).by(1).and change(Picture, :count).by(1) 9 end 10end

試したこと

1 binding.pry で Post の数と Picture の数を確認しましたが、最初の binding.pry と Post create したときの binding.pry では数が変わりませんでした。

rb

1context "with valid params" do 2 it "投稿・画像が登録されること" do 3 binding.pry 4 params = { pictures_attributes: [ attributes_for(:picture) ] } 5 post admins_posts_url, params: { post: attributes_for(:post).merge(params) } 6 binding.pry 7 # expect do 8 # post admins_posts_url, params: { post: attributes_for(:post).merge(params) } 9 # end.to change(Post, :count).by(1).and change(Picture, :count).by(1) 10 end 11end

2 paramsは取得できているか。上記の2回目の binding.pry の際、paramsの値を確認。

terminal

1{:pictures_attributes=> 2 [{:name=> 3 [#<Rack::Test::UploadedFile:0x000055eb0bb81d60 4 @content_type="spec/support/testfile.png", 5 @original_filename="testfile.png", 6 @tempfile=#<File:/tmp/testfile20200616-785-43srvt.png>>]}]}

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

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

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

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

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

Mugheart

2020/06/16 02:48

提示されている「エラーメッセージ」はエラーメセージではなく、単にテストに失敗した結果なので、そこから得られる情報は少なく、その原因を回答者が探すとなると憶測で考えなければいけない部分が多いため負担が大きいです。 まずは、なぜレコードが登録されていないのかの原因を明らかにしてください。 方法としては、ログを確認してみたり、例外を出力してみたり、binding.pry の中で実際に同じパラメータで登録を試してみたり...。 原因がわかれば解決方法も自ずとわかるとは思いますが...。
mikannOishiii

2020/06/16 05:32

ご指摘ありがとうございます。その通りですね…思考停止していました。 エラーログを追加したのでご確認いただけると嬉しいです。
Mugheart

2020/06/16 06:59

spec/factories/pictures.rb Picture name の値が配列なのは意図的ですか?正しい値ですか?
mikannOishiii

2020/06/16 07:22

意図的…ではないです!! 配列じゃなくしたら、通りました…!!凡ミスですすいません…!!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問