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

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

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

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

Ruby

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

Q&A

解決済

1回答

2395閲覧

『Rails』レコード作成前の『id』取得方法

asatosi

総合スコア23

Ruby on Rails 5

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

Ruby

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

0グッド

0クリップ

投稿2020/05/05 09:56

前提・実現したいこと

Railsにてチケット予約システムを作成します。

チケット予約時に、予約枚数と予約するチケットの種類を選択してもらいます。
※チケットの種類によってはチケット1枚で複数に入場できるものもあります。

モデルのバリエーション機能により、以下の条件を満たす時にエラーを
表示させたいと思います。

『残席数 ー (申し込みの枚数 * 申し込んだチケットで入場できる人数)< 0』

『残席数』と『申し込んだチケットで入場できる人数』の記述方法はわかるのですが、
『申し込みの枚数』をどのようにかけば良いかわかりません。

わからない理由はまだ作成されていないレコードの『id』がわからないからです。

サポートお願いします。

参考:

Ruby

1def check_ticket_limit 2 3 @@remaining = Stage.find(stage_id).remaining #残席数 4 @@num = 5       :count #予約枚数(書き方がわかりません) 6       * 7       Kind.find(kind_id).seats #人数 8 9 errors.add(:kind_id, ' 申し込みいただいた『チケット種別 / 枚数』の組み合わせではお席をご用意することができません。') 10   if @@remaining - @@num < 0 11 12 end

試したこと

Ticket.find(id).count
Ticket.find(:params[:id]).count
:count
なども駄目元でやりましたが、やっぱりだめでした。
※チケットの予約は『ticket』クラスで行なっています。

補足情報(FW/ツールのバージョンなど)

Rails 5.2.4.2
ruby 2.6.3p62

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

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

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

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

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

guest

回答1

0

ベストアンサー

『Rails』レコード作成前には『id』はありません。idはレコード作成時にDatabaseが与えるものですから。
それにレコード作成前なのですからKind.find(kind_id) とDBをアクセスしても有るはずもないです。

めもりー上に作成されているインスタンスの情報を使うようにしてください。

check_ticket_limit ってcontroller? ではないか modelのvalidationですね。
これを呼ぶに至る、 controller、このvalidationの呼び方などを載せてください。 

あ、
これって Kindモデルのvlidationですよね?

投稿2020/05/05 11:06

winterboum

総合スコア23567

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

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

asatosi

2020/05/05 12:01

Winterboum様、コメントありがとうございます。 ご質問にお答えいたします。 ①コントローラーのバリデーションを呼ぶところ def create @ticket = Ticket.new(params_ticket) validation_context = current_seller.admin_flag? ? :admin_seller : nil if @ticket.save(context: validation_context) flash[:notice] = "登録が完了しました" if params[:Renzoku] UserMailer.notice_mail_for_create_ticket(@ticket).deliver redirect_to("/tickets/new") else UserMailer.notice_mail_for_create_ticket(@ticket).deliver redirect_to("/tickets") end else render 'new' end end ②モデル『ticket』のバリデーション ※関連するところのみ class Ticket < ApplicationRecord( validate :check_ticket_limit, unless: -> { validation_context == :admin_seller } private def check_combination_of_stage_and_kind return unless Connection.find_by(stage_id: stage_id, kind_id: kind_id).invalid_flag errors.add(:stage_id, ' 選択いただいた『公演 / チケット種別』の組み合わせでは予約を承ることができません。') end def check_ticket_limit @@remaining = Stage.find(stage_id).remaining @@num = :count * Kind.find(kind_id).seats errors.add(:kind_id, ' 申し込みいただいた『チケット種別 / 枚数』の組み合わせではお席をご用意することができません。') if @@remaining - @@num < 0 end end 【回答に対するコメント】 1. 残席数のチェックにモデル『stage』、1枚のチケットで入場できる人数の確認にモデル『kind』にアクセスしますが、モデル『チケット』でのレコード作成時にエラーを出したいので、バリデーションをモデル『チケット』に記述しました。改めた方がよろしいでしょうか? 2. >めもりー上に作成されているインスタンスの情報を使うようにしてください。 なにぶん、初心者なもので、メモリ上のインスタンスへのアクセス方法が全くわかりません。 参考となるコードなどをいただけないでしょうか? よろしくお願いいたします。
asatosi

2020/05/05 12:03

書き漏らしましたが、バリデーション内の『stage_id』や『kind_id』はストロングパラメータ『params_ticket』より、取得できています。
winterboum

2020/05/05 12:11

とすると  なにのIDがない から  なにを得られないので 動かないのですか?
asatosi

2020/05/05 12:23

答えは 新しい作られるレコードの『id』がわからないから、チケット作成フォームで入力した『枚数』の情報がわからないということになります。 レコードが既に作成されている場合は Ticket.find(id).count で枚数の情報を取得できます。 しかしながら、レコード作成する前に動くバリデーションの中では『id』は確定していないので、 Ticket.find(id).count は使えないです。 winterboum様のおっしゃる通り、メモリ上に『id』があるのなら、その値を取得したいです。
winterboum

2020/05/05 13:00

controllerのチケット作成フォームで入力した『枚数』の情報 は params_ticket に有るのですよね? すると @ticket = Ticket.new(params_ticket) で@tiket に渡っていますから if @ticket.save(context: validation_context) の時のvalidationでは validationされているインスタンスが持っています。
asatosi

2020/05/05 13:57

winterboum 様 単に『count』と書けばよかったのですね。 うまくできました。 『find』とか使わないといけないのかなと考えていたのですが・・・。 今回も本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問