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

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

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

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

Q&A

1回答

119閲覧

【Rails】Validationエラーの原因がわからない

Harumaki

総合スコア0

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

0グッド

0クリップ

投稿2024/04/18 16:52

編集2024/04/19 04:04

実現したいこと

edit画面で「個人を特定できる情報が含まれていない」「公開範囲設定を確認した」の有無によって挙動を変えたい。
具体的には、チェックがある場合は編集を完了させ、チェックがない場合には同じページに戻るようにしたい。

発生している問題・分からないこと

バリデーションでエラーが出てしまい、その原因がわからない。
エラーが出る・出ないパターンは以下の通りです。
(1)チェックボックスにチェックしない
@errors=
[#<ActiveModel::Error attribute=first_agreement, type=accepted, options={:message=>"投稿するためにはチェックが必要です", :on=>:agreement_create}>,
#<ActiveModel::Error attribute=second_agreement, type=accepted, options={:message=>"投稿するためにはチェックが必要です", :on=>:agreement_create}>]>
(2)チェックボックスにチェック+登場人物を選択
@errors=[#<ActiveModel::Error attribute=characters, type=invalid, options={}>]>
(3)チェックボックスにチェック+登場人物を選択しない
true

エラーメッセージ

error

1[2] pry(#<PostsController>)> post.errors 2=> #<ActiveModel::Errors:0x000000011395bb18 3 @base= 4 #<Post:0x0000000111ad92f8 5 id: 60, 6 user_id: 2, 7 date: Tue, 09 Apr 2024, 8 around: "g", 9 title: "g", 10 reason: "g", 11 experiment: "g", 12 review: "g", 13 setting: false, 14 created_at: Tue, 09 Apr 2024 21:31:27.425144000 JST +09:00, 15 updated_at: Tue, 09 Apr 2024 21:31:27.425144000 JST +09:00>, 16 @errors=[#<ActiveModel::Error attribute=characters, type=invalid, options={}>]>

該当のソースコード

edit.htm.erb

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8</head> 9 10 11<body> 12 13 <header> 14 <%= @user.name %>の編集ページ 15 </header> 16 17 <% if flash[:notice] %> 18 <div class= "alert alert-success"> 19 <%= flash[:notice] %> 20 </div> 21 <% else %> 22 <div class= "alert alert-failure"> 23 <%= flash[:alert] %> 24 </div> 25 <% end %> 26 27 <div class="post-body"> 28 <div class="title">注意</div> 29 <div class="post-container1"> 30 <ul class="list"> 31 <li>全ての欄に記入しないと送信できません!</li> 32 <li>新しい登場人物の登録は他の情報の登録より先に行ってください!</li> 33 <li>投稿後の追記や修正も可能です!</li> 34 </ul> 35 </div> 36 37 <div class="title">新規作成</div> 38 <div class="post-container2"> 39 <%= form_with(model: @post, local: true) do |post| %> 40 41-----------------------------------------------------中略-------------------------------------------------------------- 42 43 <div class="post-content"> 44 <div class="content-title"> 45 <%= post.label :'4.登場人物を選択' %> 46 </div> 47 <div class="content-body"> 48 <ul> 49 <li>この出来事に登場する人物を選択してください。</li> 50 </ul> 51 <div class="characterfield"> 52 <%= post.collection_check_boxes :character_ids, Character.where(user_id: current_user.id), :id, :name %> 53 </div> 54 <a href="#addcharacter">ここにいない登場人物を追加する</a> 55 </div> 56 </div> 57 58-----------------------------------------------------中略-------------------------------------------------------------- 59 60 <%= post.check_box :first_agreement, :as => :boolean, checked:false %>個人を特定できる情報が含まれていない 61 <%= post.check_box :second_agreement, :as => :boolean, checked:false %>公開範囲設定を確認した 62 63 <%= post.button "編集を完了する", type: 'button', onclick: 'submit();', :class => "post-button" %> 64 65 <% end %> 66 </div> 67</body> 68 69</html>

posts_controller.rb

1class PostsController < ApplicationController 2 before_action :authenticate_user! 3 4 def edit 5 @user = User.find_by(id: current_user.id) 6 @post = Post.find(params[:id]) 7 @character = Character.new 8 end 9 10 def update 11 post = Post.find(params[:id]) 12 post.attributes = post_params 13 binding.pry 14 if post.save(context: :agreement_create) 15 if post.setting === true 16 #Announcementモデルに新規投稿のカラム作成 17 post.create_announcement_update!(current_user, post) 18 end 19 flash[:notice] = "編集できました" 20 redirect_to :action => "show_private", :id => post.id 21 else 22 flash[:alert] = "編集できませんでした" 23 @post = Post.find(params[:id]) 24 @character = Character.new 25 @user = User.find_by(id: current_user.id) 26 render "edit", :id => post.id 27 end 28 end 29 30 31 32 private 33 def post_params 34 params.require(:post).permit(:date, :around, :title, :reason, :experiment, :review, :setting, :first_agreement, :second_agreement, { :character_ids=> [] }) 35 end 36end

post.rb

1class Post < ApplicationRecord 2#登場人物 3 has_many :characters_posts, dependent: :destroy 4 has_many :characters, through: :characters_posts 5 belongs_to :user 6 7 attr_accessor :first_agreement 8 validates_acceptance_of :first_agreement, allow_nil: false, message: "投稿するためにはチェックが必要です", on: :agreement_create 9 attr_accessor :second_agreement 10 validates_acceptance_of :second_agreement, allow_nil: false, message: "投稿するためにはチェックが必要です", on: :agreement_create 11 12 validates :date, presence: true 13 validates :around, presence: true 14 validates :title, presence: true 15 validates :reason, presence: true 16 validates :experiment, presence: true 17 validates :review, presence: true 18 validates :setting, inclusion: {in: [true, false]} 19end

character.rb

1class Character < ApplicationRecord 2 belongs_to :user 3 #空欄のままデータを送らせないようにする。validates :カラム名, precence: true 4 validates :name, presence: true, uniqueness: { scope: :user_id } 5 6 attr_accessor :third_agreement 7 validates_acceptance_of :third_agreement, allow_nil: false, message: "投稿するためにはチェックが必要です" 8 9 has_many :characters_posts, dependent: :destroy 10 has_many :posts, through: :characters_posts 11end 12

characters_post.rb

1class CharactersPost < ApplicationRecord 2 belongs_to :character 3 belongs_to :post 4 5end

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

def updateの内容を以下のように書き換えましたが、同様のエラーが発生しました。

posts_controller

1post = Post.find(params[:id]) 2permitted_params = post_params.merge(first_agreement: params[:post][:first_agreement], second_agreement: params[:post][:second_agreement]) 3post.assign_attributes(permitted_params)

補足

posts_controllerで以下のようにcontextを指定しなければうまく行きます。

posts_controller

1post.save

不足している情報があれば教えてください。
何卒よろしくお願いいたします。

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

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

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

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

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

Mugheart

2024/04/19 01:20

あまりRailsでViewを書かないのでうろ覚えになってしまうんですが、Boolean型のcheckboxの書き方は ```erb <%= post.check_box :first_agreement, { checked: false }, 'true', 'false' %> ```` だったような気がします。 :as というオプションを知らなかったので、私の勉強不足でしたら申し訳ありません。 参考: https://railsdoc.com/page/check_box もしよろしければ、上記の書き方で試してみてください。
Harumaki

2024/04/19 02:44

コメントありがとうございます。 試してみましたが、やはりfalseになってしまいます。 以下のとおりです。 [2] pry(#<PostsController>)> post.save(context: :agreement_create) CACHE User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]] ↳ (pry):124:in `update' TRANSACTION (0.2ms) begin transaction ↳ (pry):124:in `update' Character Exists? (0.9ms) SELECT 1 AS one FROM "characters" WHERE "characters"."name" = ? AND "characters"."id" != ? AND "characters"."user_id" = ? LIMIT ? [["name", "おにぎりくん"], ["id", 31], ["user_id", 2], ["LIMIT", 1]] ↳ (pry):124:in `update' CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]] ↳ (pry):124:in `update' Character Exists? (0.1ms) SELECT 1 AS one FROM "characters" WHERE "characters"."name" = ? AND "characters"."id" != ? AND "characters"."user_id" = ? LIMIT ? [["name", "母親"], ["id", 30], ["user_id", 2], ["LIMIT", 1]] ↳ (pry):124:in `update' TRANSACTION (0.0ms) rollback transaction ↳ (pry):124:in `update' => false
Mugheart

2024/04/19 03:08

ご確認ありがとうございます。 validationの設定がもしかすると原因かもしれません。 回答の方に詳細を書きましたのでご確認ください。
guest

回答1

0

ドキュメントを見ると、validates_acceptance_ofで同意とみなす値の初期値は1のようです。
参考: https://railsdoc.com/page/validates_acceptance_of

質問者様は、Viewでチェックボックスの値を1, 0ではなくtrue, falseを使うようにされてますので、validates_acceptance_of:acceptオプションにてtrueを指定する必要があるのかなと思いました。

rb

1validates_acceptance_of :first_agreement, accept: true, message: "投稿するためにはチェックが必要です", on: :agreement_create 2validates_acceptance_of :second_agreement, accept: true, message: "投稿するためにはチェックが必要です", on: :agreement_create

投稿2024/04/19 03:07

Mugheart

総合スコア2349

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

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

Harumaki

2024/04/19 04:17 編集

お返事ありがとうございます。 checkboxの書き方、バリデーションともに変更して試してみました。 agreementにチェックを入れ、characterを選択した状態でpost.save(context: :agreement_create)を試すと、以下のエラーが出ました。 @errors= [#<ActiveModel::Error attribute=characters, type=invalid, options={}>, #<ActiveModel::Error attribute=first_agreement, type=accepted, options={:message=>"投稿するためにはチェックが必要です", :on=>:agreement_create}>, #<ActiveModel::Error attribute=second_agreement, type=accepted, options={:message=>"投稿するためにはチェックが必要です", :on=>:agreement_create}>]> checkbox,バリデーションを元の書き方に戻し、同じ条件で送信すると、エラーは以下のようになります。 @errors=[#<ActiveModel::Error attribute=characters, type=invalid, options={}>]> これは、checkboxのバリデーションに問題があるわけではなく、characterモデルでエラーが発生しているということなのでしょうか、、? 「発生している問題」のところに少し詳しく記載しましたので、もしお時間よろしければご確認いただけますと幸いです。
Mugheart

2024/04/19 09:27

postに紐づいているcharacterのバリデーションが引っかかっているのかもしれないですね。 すみません、質問者様の実装を詳細まで把握しきれていませんので、憶測での回答になってしまっています。 binding.pryを使って、posts_controller.rbの12行目 ```rb post.attributes = post_params ``` をした後の ```rb post.characters ``` の状態を見てみると良いかもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問