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

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

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

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

Q&A

1回答

763閲覧

NoMethodErrorを解決したいです。(おそらく変数定義の仕方が悪いです) rails

toshiki.0707

総合スコア1

Ruby on Rails

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

0グッド

0クリップ

投稿2021/07/21 07:36

前提・実現したいこと

前提
現在、Ruby on Railsを学習しており、レストランでの注文アプリを作成したいと考えています。
仕様としては
1.レストランに入って、席に置いてあるQRコードを読み取るとメニュー画面が表示される
2.メニュー一覧の商品をクリックすると、商品詳細画面に飛ぶ
3.商品詳細画面で、数量を入力して注文ボタンを押すと、カートに情報がとぶ
4.カートはsessionを用いてidを保存して、メニュー画面に戻っても、同じカートが表示される
5.カート内の商品一覧画面で注文を確定するボタンを押すとカートidが注文確定テーブルに保存され、sessionのカートidを削除する
6.席ごとに注文を判別できるように確定した注文と席の情報を結びつける
と考えております。

テーブルとしては、
1.商品を登録・表示させるためもの(Menuテーブル) 
2.注文したいものを入れるカートの役割をするためもの(Orderテーブル)
3.どの商品が何個入っているか判別するための1と2の中間テーブル(MenuOrderテーブル)
4.注文確定テーブル(OrderConfirmテーブル)
5.席番号のテーブル(Tableテーブル)
を作っています

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

お客様が注文確定したオーダーを店員が閲覧する用にMenuOrderのindexビューに全てのお客様の確定したオーダーを表示させたいと考えております。
そこでMenuOrderコントローラー内に確定したオーダーを取り出す変数@menu_ordersを定義したのですが、下記のエラーが出てしまいます。

エラーメッセージ NoMethodError in MenuOrdersController#index undefined method `order_confirms' @tables = Table.includes(:order_confirms) @menu_orders = MenuOrder.where(order_id: @tables.order_confirms.map(&:order_id))

該当のソースコード

コントローラー周り

rails

1class MenuOrdersController < ApplicationController 2 def index 3 @tables = Table.includes(:order_confirms) 4 @menu_orders = MenuOrder.where(order_id: @tables.order_confirms.map(&:order_id)) 5 end 6end

rails

1class MenusController < ApplicationController 2 before_action :set_menu, only: [:edit, :update, :show, :destroy] 3 def index 4 @menus = Menu.all.page(params[:page]).per(2) 5 end 6 def new 7 @menu = Menu.new 8 end 9 def create 10 @menu = Menu.new(menu_params) 11 if @menu.save 12 redirect_to tables_path 13 else 14 render :new 15 end 16 end 17 def edit 18 end 19 def update 20 if @menu.update(menu_params) 21 redirect_to root_path 22 else 23 render :edit 24 end 25 end 26 def destroy 27 menu.destroy 28 end 29 def show 30 @menu_order = MenuOrder.new 31 @table = Table.find(params[:table_id]) 32 end 33 34 private 35 def menu_params 36 params.require(:menu).permit(:name, :price, :image, {:tag_ids=> []}) 37 end 38 39 def set_menu 40 @menu = Menu.find(params[:id]) 41 @table = Table.find(params[:table_id]) 42 end 43end

rails

1class OrderConfirmsController < ApplicationController 2 def create 3 @order_confirm = OrderConfirm.new(order_confirm_params) 4 @order = Order.find(@order_confirm.order_id) 5 if @order_confirm.save 6 session.delete(:order_id) 7 else 8 render "orders/my_order" 9 end 10 end 11 def destroy 12 13 end 14 15 private 16 17 def order_confirm_params 18 params.require(:order_confirm).permit(:order_id).merge(table_id: params[:table_id]) 19 end 20end

rails

1class OrdersController < ApplicationController 2 before_action :setup_order_menu!, only: [:add_menu, :update_menu, :delete_menu] 3 4 def my_order 5 @menu_orders = current_order.menu_orders.includes([:menu]) 6 @total = @menu_orders.inject(0){ |sum, item| sum + item.sum_of_price } 7 @order_confirm = OrderConfirm.new 8 @table = Table.find(params[:table_id]) 9 end 10 11 # 商品一覧画面から、「商品購入」を押した時のアクション 12 def add_menu 13 @menu_order ||= MenuOrder.new(order_id: current_order.id, menu_id: params[:menu_id], table_num: params[:table_num]) 14 @menu_order.quantity += params[:quantity].to_i 15 if @menu_order.save 16 flash[:notice] = '注文を追加しました' 17 redirect_to table_my_order_path(params[:table_id]) 18 else 19 flash[:alert] = '注文の追加に失敗しました' 20 redirect_to table_menu_url(table_id: params[:table_id], id: params[:menu_id]) 21 end 22 end 23 24 # カート詳細画面から、「更新」を押した時のアクション 25 def update_menu 26 @menu_order.update(quantity: params[:quantity].to_i) 27 redirect_to table_my_order_path(params[:table_id]) 28 end 29 30 # カート詳細画面から、「削除」を押した時のアクション 31 def delete_menu 32 @menu_order.destroy 33 redirect_to table_my_order_path(params[:table_id]) 34 end 35 36 private 37 38 def setup_order_menu! 39 @menu_order = current_order.menu_orders.find_by(menu_id: params[:menu_id]) 40 end 41end 42

rails

1class TablesController < ApplicationController 2 before_action :authenticate_user!, except: :show 3 def index 4 @tables = Table.includes(:order_confirms) 5 end 6 def new 7 @table = Table.new 8 end 9 def create 10 @table = Table.new(table_params) 11 if @table.save 12 redirect_to tables_path 13 else 14 render :new 15 end 16 end 17 def show 18 @table = Table.find(params[:id]) 19 @menu_orders = MenuOrder.where(order_id: @table.order_confirms.map(&:order_id)) 20 end 21 def destroy 22 @table = Table.find(params[:id]) 23 if @table.destroy 24 redirect_to tables_path 25 else 26 render :show 27 end 28 end 29 30 private 31 32 def table_params 33 params.require(:table).permit(:table_num) 34 end 35 36end

ルーティング

rails

1Rails.application.routes.draw do 2 devise_for :users 3 root 'tables#index' 4 resources :tables, only: [:index, :new, :create, :show, :destroy] do 5 resources :menus, only: [:index, :show] 6 resources :orders, only: [:new, :create] 7 get '/my_order' => 'orders#my_order' 8 post '/add_menu' => 'orders#add_menu' 9 post '/update_menu' => 'orders#update_menu' 10 delete '/delete_menu' => 'orders#delete_menu' 11 resources :order_confirms, only: [:create, :destroy] 12 end 13 resources :menus, only: [:new, :create, :edit, :update, :destroy] 14 resources :menu_orders, only: :index 15end 16

モデル周り

rails

1class MenuOrder < ApplicationRecord 2 belongs_to :menu 3 belongs_to :order 4 5 def sum_of_price 6 menu.price * quantity 7 end 8 9 validates :table_num, presence: true 10end 11

rails

1class Menu < ApplicationRecord 2 has_one_attached :image 3 has_many :menu_orders, dependent: :destroy 4 has_many :order, through: :menu_orders, dependent: :destroy 5 has_many :menu_tag_relations, dependent: :destroy 6 has_many :tags, through: :menu_tag_relations, dependent: :destroy 7 8 validates :name, presence: true 9 validates :price, numericality: { only_integer: true } 10end

rails

1class OrderConfirm < ApplicationRecord 2 belongs_to :order 3 belongs_to :table 4end 5

rails

1class Order < ApplicationRecord 2 has_many :menu_orders, dependent: :destroy 3 has_many :menus, through: :menu_orders, dependent: :destroy 4 has_one :order_confirm, dependent: :destroy 5end

rails

1class Table < ApplicationRecord 2 has_many :order_confirms, dependent: :destroy 3 4end 5

rails

1class User < ApplicationRecord 2 # Include default devise modules. Others available are: 3 # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable 4 devise :database_authenticatable, :registerable, 5 :recoverable, :rememberable, :validatable 6 7 validates :nickname, presence: true 8end 9

試したこと

似たような変数定義をした際に、tableを一つに指定した場合にはエラーが出ずに変数定義をすることが出来ました。そのため、tableのレコードが複数あることで何か問題が起きてしまっているのだと考えました。この仮説があっている場合、tableが複数の時にはどのように記述すれば、確定したオーダーを全て抽出することができるでしょうか。

また、エラーとは別件になりますが、現在オーダーを確定するのにオーダー確定テーブルを用いて確定をしています。
しかし、以前別のエラーで質問した際に回答いただいた方に、statusを用いればオーダーテーブルのみでオーダーを確定させることができるとのアドバイスをいただきました。ただ、自分の調べ方が悪いのかそのようなやり方を発見することができませんでした。わかる方がいらっしゃれば、オーダーのみでオーダーを確定させる方法をお教えいただくか、もしくは参考にできる記事等をお教えいただけますでしょうか。

以上、2点についてご教示いただけますでしょうか。

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

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

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

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

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

guest

回答1

0

エラーメッセージのとおりです。コレクションである@tablesから直接order_confirmsを参照することはできません。

投稿2021/07/21 07:39

maisumakun

総合スコア145208

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

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

maisumakun

2021/07/21 07:42

Tableモデルにhas_many :order, through: :order_confirmを定義して、そこからordersを取るのが楽かもしれません。
maisumakun

2021/07/21 07:46

> 現在オーダーを確定するのにオーダー確定テーブルを用いて確定をしています。 orderがたかだか1つのテーブルにしか結びつかない以上、order側にtable_idをもたせれば、中間テーブルは不要です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問