我正在研究饭店应用的代码。我现在被困住了,我不了解订单和项目之间的关系。看起来有一个联合表,但我不了解它的逻辑。这是模式的代码`
ActiveRecord::Schema.define(version: 20160327212111) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "items", force: :cascade do |t|
t.string "name"
t.string "cuisine_type"
t.integer "price"
end
create_table "items_orders", id: false, force: :cascade do |t|
t.integer "order_id", null: false
t.integer "item_id", null: false
end
add_index "items_orders", ["item_id", "order_id"], name: "index_items_orders_on_item_id_and_order_id", using: :btree
add_index "items_orders", ["order_id", "item_id"], name: "index_items_orders_on_order_id_and_item_id", using: :btree
create_table "orders", force: :cascade do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.integer "party_id"
t.boolean "paid?", default: false
end
end
在这里,控制器命令的创建方法使我更加困惑。
def create
food_items = params[:item][:item_id].drop(1).map{ |item| item.to_i}
@items = Item.where("id in (?)", food_items)
@order = Order.new(order_params)
# items_array = params[:item]["item_id"].drop(1)
if @order.save
@items.each { |item| @order.items << item }
redirect_to orders_path
else
redirect_to new_order_path
end
end
谢谢您的帮助。
商品和订单的更新模型
class Item < ActiveRecord::Base
has_and_belongs_to_many :orders
end
class Order < ActiveRecord::Base
has_and_belongs_to_many :items
has_one :party
end
物品和订单控制器
class ItemsController < ApplicationController
def index
@item = Item.all
end
def show
@item = Item.find(params[:id])
end
def new
@item = Item.new
end
def create
@item = Item.new(item_params)
if @item.save
redirect_to items_path
else
redirect_to new_item_path
end
end
def edit
@item = Item.find(params[:id])
end
def update
@item = Item.find(params[:id])
@item.update(item_params)
redirect_to items_path
end
def destroy
@item = Item.find(params[:id])
@item.destroy
redirect_to items_path
end
private
def item_params
params.require(:item).permit(:name, :cuisine_type, :price)
end
end
class OrdersController < ApplicationController
def index
@orders = Order.order(:party_id)
@items = Item.all
@parties = Party.all
end
def show
@orders = Order.find(params[:id])
end
def new
@order = Order.new
@orders = Order.all
@items = Item.all
@parties = Party.all
end
def create
puts "Item ids #{params[:item][:item_id]}"
food_items = params[:item][:item_id].drop(1).map{ |item| item.to_i}
@items = Item.where("id in (?)", food_items)
@order = Order.new(order_params)
# items_array = params[:item]["item_id"].drop(1)
if @order.save
@items.each { |item|
@order.items << item
}
redirect_to orders_path
else
redirect_to new_order_path
end
end
def destroy
@order = Order.find(params[:id])
@order.destroy
redirect_to orders_path
end
private
def order_params
params.require(:order).permit(:party_id, :item_id)
end
end
答案 0 :(得分:0)
根据您的架构,您必须在Order
和Item
类之间建立has-and-belongs-to-many关联。
免责声明: It can easily be has-many-through关联而不是HABTM,但在联接表 items_orders 中没有看到任何多余的列。同样,您也没有提到ItemsOrder
模型的任何特殊用途(如果存在)。因此,我将使用简单的HABTM。
型号:
class Order
has_and_belongs_to_many :items
end
class Item
has_and_belongs_to_many :orders
end
有了这些关联,您可以执行以下操作:
# Say, you have some items in your database
item = Item.take
=> #<Item id: 1>
Order.count
=> 0
# Create a new order and assign `item` to it
order = Order.new
order.items << item
order.save!
以上语句集将在连接表中插入一条新记录,如下所示:
| id | order_id | item_id |
| 1 | 1 | 1 |
现在,您可以按以下顺序检查订单中显示的商品:
order.items
=> [#<Item id: 1>, ...]
或相反:
item.orders
=> [#<Order id: 1>, ...]
现在,让我们浏览一下控制器代码:
def create
# I don't know what `params[:item][:item_id]` contains, but `drop` method drops the first n (in this case, 1) number of elements and returns the remaining array
# ... and map is changing each element from whatever format to integer format
# Read more:
# - https://apidock.com/ruby/Array/drop
# - https://apidock.com/ruby/Array/map
food_items = params[:item][:item_id].drop(1).map { |item| item.to_i }
# Searching for items with ID ANY IN given array of IDs
@items = Item.where("id in (?)", food_items)
# Initialize a new order with permitted params (hopefully). Check definition of `order_params `
@order = Order.new(order_params)
if @order.save
# Assigning each searched item to new order, which will create as many new records in join table as the number of `@items`
@items.each { |item| @order.items << item }
# The usual
redirect_to orders_path
else
# Shouldn't it be render, and not redirect
redirect_to new_order_path
end
end
希望有帮助。