前提・実現したいこと
前提
現在、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テーブル)
を作っています
発生している問題・エラーメッセージ
注文確定された商品を出力するためにテーブルコントローラーで下記を定義しましたが
def show
@table = Table.find(params[:id])
@menu_orders = MenuOrder.where(order_id: @table.order_confirms.order_id)
end
をで定義しましたが、下記のエラーがでます。
NoMethodError in TablesController#show
undefined method `order_id' for #OrderConfirm::ActiveRecord_Associations_CollectionProxy:0x00007fa345f5e3e0 Did you mean? order
どこか記述が間違っているのでしょうか。また、エラーを解消してもこの記述では出力できない等はありますでしょうか。
該当のソースコード
ルーティング
ruby
1Rails.application.routes.draw do 2 root 'menus#index' 3 resources :tables, only: [:index, :new, :create, :show] do 4 resources :menus 5 resources :orders, only: [:new, :create] 6 get '/my_order' => 'orders#my_order' 7 post '/add_menu' => 'orders#add_menu' 8 post '/update_menu' => 'orders#update_menu' 9 delete '/delete_menu' => 'orders#delete_menu' 10 resources :order_confirms, only: [:create, :destroy] 11 end 12end
モデル周り
ruby
1class Table < ApplicationRecord 2 has_many :order_confirms 3end 4
ruby
1class Order < ApplicationRecord 2 has_many :menu_orders, dependent: :destroy 3 has_many :menus, through: :menu_orders 4 has_one :order_confirm 5end 6
ruby
1class OrderConfirm < ApplicationRecord 2 belongs_to :order 3 belongs_to :table 4end
ruby
1class Menu < ApplicationRecord 2 has_one_attached :image 3 has_many :menu_orders, dependent: :destroy 4 validates :price, numericality: { only_integer: true } 5 validates :name, presence: true 6 has_many :order, through: :menu_orders 7end
ruby
1class MenuOrder < ApplicationRecord 2 belongs_to :menu 3 belongs_to :order 4 5 def sum_of_price 6 menu.price * quantity 7 end 8end
コントローラー周り
ruby
1class TablesController < ApplicationController 2 def index 3 @tables = Table.includes(:order_confirms) 4 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.order_id) 20 end 21 22 private 23 24 def table_params 25 params.require(:table).permit(:table_num) 26 end 27 28end
ruby
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 end 9 10 # 商品一覧画面から、「商品購入」を押した時のアクション 11 def add_menu 12 @menu_order ||= MenuOrder.new(order_id: current_order.id, menu_id: params[:menu_id]) 13 @menu_order.quantity += params[:quantity].to_i 14 if @menu_order.save 15 flash[:notice] = '注文を追加しました' 16 redirect_to table_my_order_path(params[:table_id]) 17 else 18 flash[:alert] = '注文の追加に失敗しました' 19 redirect_to table_menu_url(table_id: params[:table_id], id: params[:menu_id]) 20 end 21 end 22 23 # カート詳細画面から、「更新」を押した時のアクション 24 def update_menu 25 @menu_order.update(quantity: params[:quantity].to_i) 26 redirect_to table_my_order_path(params[:table_id]) 27 end 28 29 # カート詳細画面から、「削除」を押した時のアクション 30 def delete_menu 31 @menu_order.destroy 32 redirect_to table_my_order_path(params[:table_id]) 33 end 34 35 private 36 37 def setup_order_menu! 38 @menu_order = current_order.menu_orders.find_by(menu_id: params[:menu_id]) 39 end 40end
ruby
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 21
ruby
1class MenusController < ApplicationController 2 def index 3 @menus = Menu.all 4 end 5 def new 6 @menu = Menu.new 7 end 8 def create 9 @menu = Menu.new(menu_params) 10 if @menu.save 11 redirect_to root_path 12 else 13 render :new 14 end 15 end 16 def edit 17 @menu = Menu.find(params[:id]) 18 end 19 def update 20 @menu = Menu.find(params[:id]) 21 if @menu.update(menu_params) 22 redirect_to root_path 23 else 24 render :edit 25 end 26 end 27 def destroy 28 menu = Menu.find(params[:id]) 29 menu.destroy 30 end 31 def show 32 @menu = Menu.find(params[:id]) 33 @menu_order = MenuOrder.new 34 end 35 36 private 37 def menu_params 38 params.require(:menu).permit(:name, :price, :image) 39 end 40end
マイグレーション
ruby
1class CreateMenus < ActiveRecord::Migration[6.0] 2 def change 3 create_table :menus do |t| 4 t.string :name, null: false 5 t.integer :price, null: false 6 t.timestamps 7 end 8 end 9end
ruby
1# This migration comes from active_storage (originally 20170806125915) 2class CreateActiveStorageTables < ActiveRecord::Migration[5.2] 3 def change 4 create_table :active_storage_blobs do |t| 5 t.string :key, null: false 6 t.string :filename, null: false 7 t.string :content_type 8 t.text :metadata 9 t.bigint :byte_size, null: false 10 t.string :checksum, null: false 11 t.datetime :created_at, null: false 12 13 t.index [ :key ], unique: true 14 end 15 16 create_table :active_storage_attachments do |t| 17 t.string :name, null: false 18 t.references :record, null: false, polymorphic: true, index: false 19 t.references :blob, null: false 20 21 t.datetime :created_at, null: false 22 23 t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true 24 t.foreign_key :active_storage_blobs, column: :blob_id 25 end 26 end 27end 28
ruby
1class CreateOrders < ActiveRecord::Migration[6.0] 2 def change 3 create_table :orders do |t| 4 t.timestamps 5 end 6 end 7end
ruby
1class CreateMenuOrders < ActiveRecord::Migration[6.0] 2 def change 3 create_table :menu_orders do |t| 4 t.integer :quantity, default: 0 5 t.references :menu, null: false, foreign_key: true 6 t.references :order, null: false, foreign_key: true 7 t.timestamps 8 end 9 end 10end
ruby
1class CreateTables < ActiveRecord::Migration[6.0] 2 def change 3 create_table :tables do |t| 4 t.integer :table_num, null: false 5 t.timestamps 6 end 7 end 8end 9
ruby
1class CreateOrderConfirms < ActiveRecord::Migration[6.0] 2 def change 3 create_table :order_confirms do |t| 4 t.references :order, null: false, foreign_key: true 5 t.references :table, null: false, foreign_key: true 6 t.timestamps 7 end 8 end 9end
テーブルのshowビュー
ruby
1<main class="main"> 2 <div class="card__wrapper"> 3 <%= render partial: "table", locals: {table: @table} %> 4 <% @menu_orders.each do |order| %> 5 <%= order.menu.name %> 6 <% end %> 7 </div> 8 <div> 9 <%= link_to "メニュー画面へ", table_menus_path(@table.id) %> 10 </div> 11</main>
試したこと
order_confirmテーブル上にorder_idカラムがあり、データが保存されていたため、order_idがないわけではない。そのためアソシエーションに問題があるのではと考え、tableとorder_confirmのアソシエーションを見てみたが、問題は発見できなかった。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/07/15 08:09 編集
2021/07/15 08:59
2021/07/16 01:59