Rails 6 table 关联用户 table 与项目 table 关联
Rails 6 table association user table in association with items table
您好,我正在尝试创建一个包含用户正在销售的商品的应用。我有一个 table 用于销售商品的用户和一个 table 用于商品,但我对如何为买家设置下一个 table 感到有点困惑。我有一个单独的 table,它在用户和项目跟踪 user_id 和 item_id 之间是多对多的。我应该创建一个类似的 table 跟踪 buyer_id 和 item_id 吗?我希望能够跟踪从哪个用户那里购买了哪些商品,反之亦然。用户和买家来自同一用户 table.
谢谢!
编辑:
class UsersController < ApplicationController
def my_page
@user = current_user
@seller_items = current_user.seller_orders.map { |so| so.order_items.map { |oi| { item: oi.item } } }.flatten
@seller_items.to_a
end
end
您确实需要中间的东西 - 这在电子商务中通常称为“订单”:
- Link 给用户
- Link 到项目
但也许还有更多属性:
- 发售日期
- 状态 (cart/order/paid/delivered)
所以确实 - 你会想要一个额外的模型
class Seller < ApplicationRecord
belongs_to :user
has_many selling_items
has_many :items, through: :selling_items
end
class Buyer < ApplicationRecord
belongs_to :user
has_many bought_items
has_many :items, through: :bought_items
end
class Items < ApplicationRecord
end
class BoughtItem < ApplicationRecord
belongs_to :buyer
belongs_to :item
end
class SellingItem < ApplicationRecord
belongs_to :seller
belongs_to :item
end
class User < ApplicationRecord
end
一个更完整的答案,更少的模型和命名连接。您可能希望“合并”订单表和 order_items 表,如果您处理的是单个待售商品,则删除多个表,例如汽车,但对于任何批量购买或可能与其他东西同时出售的东西,您可能需要这种布局:
生成模型:
rails g model User name:string
rails g model Item name:string
rails g model Order order_date:time status:string
rails g model OrderItem order:references item:references multiple:integer
修改create_order以添加附加参考:
def change
create_table :orders do |t|
t.time :order_date, index: true, null: false
t.string :status
t.references :buyer, index: true, null: false, foreign_key: {to_table: :users}
t.references :seller, index: true, null: false, foreign_key: {to_table: :users}
t.timestamps
end
迁移模型:
rake db:migrate
== 20201126090851 CreateUsers: migrating ======================================
-- create_table(:users)
-> 0.0036s
== 20201126090851 CreateUsers: migrated (0.0039s) =============================
== 20201126090858 CreateItems: migrating ======================================
-- create_table(:items)
-> 0.0030s
== 20201126090858 CreateItems: migrated (0.0032s) =============================
== 20201126091129 CreateOrders: migrating =====================================
-- create_table(:orders)
-> 0.0077s
== 20201126091129 CreateOrders: migrated (0.0081s) ============================
== 20201126091209 CreateOrderItems: migrating =================================
-- create_table(:order_items)
-> 0.0065s
== 20201126091209 CreateOrderItems: migrated (0.0067s) ========================
修改模型以添加连接:
app/models/user.rb
::::::::::::::
class User < ApplicationRecord
has_many :buyer_orders, class_name: "Order", foreign_key: :buyer, inverse_of: :buyer
has_many :seller_orders, class_name: "Order", foreign_key: :seller, inverse_of: :seller
end
::::::::::::::
app/models/item.rb
::::::::::::::
class Item < ApplicationRecord
has_many :order_items, inverse_of: :item
end
::::::::::::::
app/models/order.rb
::::::::::::::
class Order < ApplicationRecord
has_many :order_items, inverse_of: :order
belongs_to :seller, class_name: "User", inverse_of: :seller_orders
belongs_to :buyer, class_name: "User", inverse_of: :buyer_orders
end
::::::::::::::
app/models/order_item.rb
::::::::::::::
class OrderItem < ApplicationRecord
belongs_to :order, inverse_of: :order_items
belongs_to :item, inverse_of: :order_items
end
插入数据:
User.create(name: "hello")
User.create(name: "again")
Item.create(name: "whatever")
Order.create(buyer: User.first, seller: User.last, order_date: Time.now())
OrderItem.create(item: Item.first, order: Order.first, multiple: 1)
测试输出:
查看订单状态:
2.7.0 :002 > Order.first
(0.5ms) SELECT sqlite_version(*)
Order Load (0.2ms) SELECT "orders".* FROM "orders" ORDER BY "orders"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<Order id: 1, order_date: "2000-01-01 09:26:22", status: nil, buyer_id: 1, seller_id: 2, created_at: "2020-11-26 09:26:22", updated_at: "2020-11-26 09:26:22">
2.7.0 :003 > Order.first.seller
Order Load (0.2ms) SELECT "orders".* FROM "orders" ORDER BY "orders"."id" ASC LIMIT ? [["LIMIT", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
=> #<User id: 2, name: "again", created_at: "2020-11-26 09:25:26", updated_at: "2020-11-26 09:25:26">
2.7.0 :004 > Order.first.buyer
Order Load (0.2ms) SELECT "orders".* FROM "orders" ORDER BY "orders"."id" ASC LIMIT ? [["LIMIT", 1]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "hello", created_at: "2020-11-26 09:25:18", updated_at: "2020-11-26 09:25:18">
查看第一个用户的“买家订单”:
2.7.0 :013 > User.first.buyer_orders
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
Order Load (0.3ms) SELECT "orders".* FROM "orders" WHERE "orders"."buyer_id" = ? LIMIT ? [["buyer_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Order id: 1, order_date: "2000-01-01 09:26:22", status: nil, buyer_id: 1, seller_id: 2, created_at: "2020-11-26 09:26:22", updated_at: "2020-11-26 09:26:22">]>
查看第二个用户的“卖家订单”:
2.7.0 :014 > User.last.seller_orders
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT ? [["LIMIT", 1]]
Order Load (0.3ms) SELECT "orders".* FROM "orders" WHERE "orders"."seller_id" = ? LIMIT ? [["seller_id", 2], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Order id: 1, order_date: "2000-01-01 09:26:22", status: nil, buyer_id: 1, seller_id: 2, created_at: "2020-11-26 09:26:22", updated_at: "2020-11-26 09:26:22">]>
为了省心,请检查第一个用户没有任何卖家订单:
2.7.0 :015 > User.first.seller_orders
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
Order Load (0.2ms) SELECT "orders".* FROM "orders" WHERE "orders"."seller_id" = ? LIMIT ? [["seller_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy []>
2.7.0 :016 >
控制器
class UsersController < ApplicationController
def my_page
@user = current_user
@seller_orders = current_user.seller_orders
# remember that you might want to filter this in the future
# from_date = params[:from_date].present? ? params[:from_date] : Time.at(0)
# to_date = params[:to_date].present? ? params[:to_date] : Time.now()
# @seller_orders = @seller_orders.where(order_date: from_date..to_date)
end
end
查看(我用的是haml)
%h1
= @user.username
Seller Orders
- @seller_orders.each do |so|
%table.seller_order{id: "seller_order_#{so.id}"}
%tr
%th Order Date:
%td= so.order_date
%tr
%th Buyer:
%td= so.buyer.username
%tr.spacer
%td{colspan: 2}
%tr
%th Item
%th Multiple
- so.order_items.each do |oi|
%tr
%td= oi.item.name
%td= oi.multiple
卖家商品
@seller_items = @seller_orders.map{|so| so.order_items.map{|oi| {multiple: oi.multiple, item: oi.item} }.flatten
或者可能(凭记忆写的,未经测试)
@seller_items = OrderItem.select("sum(order_items.multiple) as multiple, order_items.item_id as item_id").joins(:orders).joins(:buyer).where("users.id = ?", User.first.id).group("item_id")
您好,我正在尝试创建一个包含用户正在销售的商品的应用。我有一个 table 用于销售商品的用户和一个 table 用于商品,但我对如何为买家设置下一个 table 感到有点困惑。我有一个单独的 table,它在用户和项目跟踪 user_id 和 item_id 之间是多对多的。我应该创建一个类似的 table 跟踪 buyer_id 和 item_id 吗?我希望能够跟踪从哪个用户那里购买了哪些商品,反之亦然。用户和买家来自同一用户 table.
谢谢!
编辑:
class UsersController < ApplicationController
def my_page
@user = current_user
@seller_items = current_user.seller_orders.map { |so| so.order_items.map { |oi| { item: oi.item } } }.flatten
@seller_items.to_a
end
end
您确实需要中间的东西 - 这在电子商务中通常称为“订单”:
- Link 给用户
- Link 到项目
但也许还有更多属性:
- 发售日期
- 状态 (cart/order/paid/delivered)
所以确实 - 你会想要一个额外的模型
class Seller < ApplicationRecord
belongs_to :user
has_many selling_items
has_many :items, through: :selling_items
end
class Buyer < ApplicationRecord
belongs_to :user
has_many bought_items
has_many :items, through: :bought_items
end
class Items < ApplicationRecord
end
class BoughtItem < ApplicationRecord
belongs_to :buyer
belongs_to :item
end
class SellingItem < ApplicationRecord
belongs_to :seller
belongs_to :item
end
class User < ApplicationRecord
end
一个更完整的答案,更少的模型和命名连接。您可能希望“合并”订单表和 order_items 表,如果您处理的是单个待售商品,则删除多个表,例如汽车,但对于任何批量购买或可能与其他东西同时出售的东西,您可能需要这种布局:
生成模型:
rails g model User name:string
rails g model Item name:string
rails g model Order order_date:time status:string
rails g model OrderItem order:references item:references multiple:integer
修改create_order以添加附加参考:
def change
create_table :orders do |t|
t.time :order_date, index: true, null: false
t.string :status
t.references :buyer, index: true, null: false, foreign_key: {to_table: :users}
t.references :seller, index: true, null: false, foreign_key: {to_table: :users}
t.timestamps
end
迁移模型:
rake db:migrate
== 20201126090851 CreateUsers: migrating ======================================
-- create_table(:users)
-> 0.0036s
== 20201126090851 CreateUsers: migrated (0.0039s) =============================
== 20201126090858 CreateItems: migrating ======================================
-- create_table(:items)
-> 0.0030s
== 20201126090858 CreateItems: migrated (0.0032s) =============================
== 20201126091129 CreateOrders: migrating =====================================
-- create_table(:orders)
-> 0.0077s
== 20201126091129 CreateOrders: migrated (0.0081s) ============================
== 20201126091209 CreateOrderItems: migrating =================================
-- create_table(:order_items)
-> 0.0065s
== 20201126091209 CreateOrderItems: migrated (0.0067s) ========================
修改模型以添加连接:
app/models/user.rb
::::::::::::::
class User < ApplicationRecord
has_many :buyer_orders, class_name: "Order", foreign_key: :buyer, inverse_of: :buyer
has_many :seller_orders, class_name: "Order", foreign_key: :seller, inverse_of: :seller
end
::::::::::::::
app/models/item.rb
::::::::::::::
class Item < ApplicationRecord
has_many :order_items, inverse_of: :item
end
::::::::::::::
app/models/order.rb
::::::::::::::
class Order < ApplicationRecord
has_many :order_items, inverse_of: :order
belongs_to :seller, class_name: "User", inverse_of: :seller_orders
belongs_to :buyer, class_name: "User", inverse_of: :buyer_orders
end
::::::::::::::
app/models/order_item.rb
::::::::::::::
class OrderItem < ApplicationRecord
belongs_to :order, inverse_of: :order_items
belongs_to :item, inverse_of: :order_items
end
插入数据:
User.create(name: "hello")
User.create(name: "again")
Item.create(name: "whatever")
Order.create(buyer: User.first, seller: User.last, order_date: Time.now())
OrderItem.create(item: Item.first, order: Order.first, multiple: 1)
测试输出:
查看订单状态:
2.7.0 :002 > Order.first
(0.5ms) SELECT sqlite_version(*)
Order Load (0.2ms) SELECT "orders".* FROM "orders" ORDER BY "orders"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<Order id: 1, order_date: "2000-01-01 09:26:22", status: nil, buyer_id: 1, seller_id: 2, created_at: "2020-11-26 09:26:22", updated_at: "2020-11-26 09:26:22">
2.7.0 :003 > Order.first.seller
Order Load (0.2ms) SELECT "orders".* FROM "orders" ORDER BY "orders"."id" ASC LIMIT ? [["LIMIT", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
=> #<User id: 2, name: "again", created_at: "2020-11-26 09:25:26", updated_at: "2020-11-26 09:25:26">
2.7.0 :004 > Order.first.buyer
Order Load (0.2ms) SELECT "orders".* FROM "orders" ORDER BY "orders"."id" ASC LIMIT ? [["LIMIT", 1]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "hello", created_at: "2020-11-26 09:25:18", updated_at: "2020-11-26 09:25:18">
查看第一个用户的“买家订单”:
2.7.0 :013 > User.first.buyer_orders
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
Order Load (0.3ms) SELECT "orders".* FROM "orders" WHERE "orders"."buyer_id" = ? LIMIT ? [["buyer_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Order id: 1, order_date: "2000-01-01 09:26:22", status: nil, buyer_id: 1, seller_id: 2, created_at: "2020-11-26 09:26:22", updated_at: "2020-11-26 09:26:22">]>
查看第二个用户的“卖家订单”:
2.7.0 :014 > User.last.seller_orders
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT ? [["LIMIT", 1]]
Order Load (0.3ms) SELECT "orders".* FROM "orders" WHERE "orders"."seller_id" = ? LIMIT ? [["seller_id", 2], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Order id: 1, order_date: "2000-01-01 09:26:22", status: nil, buyer_id: 1, seller_id: 2, created_at: "2020-11-26 09:26:22", updated_at: "2020-11-26 09:26:22">]>
为了省心,请检查第一个用户没有任何卖家订单:
2.7.0 :015 > User.first.seller_orders
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
Order Load (0.2ms) SELECT "orders".* FROM "orders" WHERE "orders"."seller_id" = ? LIMIT ? [["seller_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy []>
2.7.0 :016 >
控制器
class UsersController < ApplicationController
def my_page
@user = current_user
@seller_orders = current_user.seller_orders
# remember that you might want to filter this in the future
# from_date = params[:from_date].present? ? params[:from_date] : Time.at(0)
# to_date = params[:to_date].present? ? params[:to_date] : Time.now()
# @seller_orders = @seller_orders.where(order_date: from_date..to_date)
end
end
查看(我用的是haml)
%h1
= @user.username
Seller Orders
- @seller_orders.each do |so|
%table.seller_order{id: "seller_order_#{so.id}"}
%tr
%th Order Date:
%td= so.order_date
%tr
%th Buyer:
%td= so.buyer.username
%tr.spacer
%td{colspan: 2}
%tr
%th Item
%th Multiple
- so.order_items.each do |oi|
%tr
%td= oi.item.name
%td= oi.multiple
卖家商品
@seller_items = @seller_orders.map{|so| so.order_items.map{|oi| {multiple: oi.multiple, item: oi.item} }.flatten
或者可能(凭记忆写的,未经测试)
@seller_items = OrderItem.select("sum(order_items.multiple) as multiple, order_items.item_id as item_id").joins(:orders).joins(:buyer).where("users.id = ?", User.first.id).group("item_id")