【问题标题】:Rails 6 table association user table in association with items tableRails 6 表关联用户表与项目表关联
【发布时间】:2020-11-26 02:53:51
【问题描述】:

您好,我正在尝试创建一个包含用户正在销售的商品的应用。我有一张供销售商品的用户使用的表格和一张供商品使用的表格,但我对如何为买家设置下一张桌子有点困惑。我有一个单独的表,它在用户和项目跟踪 user_id 和 item_id 之间是多对多的。我应该创建一个类似的表来跟踪buyer_id 和item_id 吗?我希望能够跟踪从哪个用户那里购买了哪些商品,反之亦然。 User 和 Buyers 来自同一个 User 表。

谢谢!

编辑:

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

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 ruby-on-rails-5


    【解决方案1】:

    一个更完整的答案,更少的模型和命名的连接。您可能想要“合并” order 和 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} &nbsp;
        %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")
    

    【讨论】:

    • 谢谢@jad,这很有帮助,但我如何才能访问每个卖家商品和每个买家商品?我是否必须遍历每个用户 Seller_orders 以查找 order_id,然后使用 order_id 查找 item_id,然后返回 items 表以按 id 搜索项目?您可以通过任何方式在控制台上向我展示以进行访问,我们将不胜感激!
    • 我正试图弄清楚如何将卖家和买家的物品放在浏览器中。谢谢
    • x=User.first; x.seller_orders.map{|so| [so.multiple, so.item]} 将返回一个包含所有项目和倍数的数组,在我的示例中为第一个用户
    • 我收到一个 NoMethodError(未定义的方法 `item' for #<0x000000000af96f28>
    【解决方案2】:

    你确实需要一些中间的东西——这在电子商务中通常被称为“订单”:

    • 链接到用户
    • 项目链接

    但也许还有更多属性:

    • 销售日期
    • 状态(购物车/订单/已付款/已交付)

    确实如此 - 你会想要一个额外的模型

    【讨论】:

      【解决方案3】:
      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
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-03
        • 1970-01-01
        • 1970-01-01
        • 2014-03-24
        • 1970-01-01
        • 1970-01-01
        • 2014-01-16
        • 1970-01-01
        相关资源
        最近更新 更多