【问题标题】:Rails association on 3 tables, without "ID"?3 个表上的 Rails 关联,没有“ID”?
【发布时间】:2022-12-13 05:14:45
【问题描述】:

所以我正在学习 Ruby on Rails,我正在深入研究数据库模型。我被协会困住了。 用例:我在港口开展业务,(小型)船只来这里运送产品,然后卡车运走产品。所以一个经典的仓库“thingy”。我希望能够查看我的仓库(“任何仓库中有多少产品”?)。 我附上了一张照片,其中包含三个表格:“产品、仓库、订单”。我让它在产品和订单之间工作,现在想整合仓库。

条件: a) 橙色标记字段“产品参考”是“相关”搜索条件,因此无论何时船舶运入或卡车运出物品,都会被该(字符串)字段引用。带有这个“prodref”字段的产品表是唯一的事实。

b) 一个产品可以在多个仓库(1:n关联)

c) 对于每个进/出的产品,需要一个单一的订单。没有“一个订单5个产品”这样的事情。 (这将是 1:1 关联)。当一艘船运送 5 件产品时,就会创建 5 个订单。

d) 每个订单现在都应该更新仓库的“金额”栏。

在 Rails 层面,我遇到了两个问题:

  1. 我想理解,Rails 的良好实践说,关联应该在 ID 级别(整数),并且生成带有“引用”的模型会自动执行。当我在产品和仓库之间建立关联时(一个产品属于一个仓库,一个仓库有很多产品),那么我仅限于创造新产品。该协会迫使我也分配一个仓库(数量可能为“0”)。我觉得我应该能够“预先”创建产品,只有当船进来时,我才会将产品分配到仓库。

  2. 更新仓库表中每个订单的金额列订单:(紫色箭头)。为了容易上手,我假设只有一个仓库。一个仓库没有订单,订单不属于仓库……所以我没有订单和仓库的关系。继续只使用 fk_prodref 的想法,我的订单中已经有了 fk_prodref(从产品表中捕获)。所以我的订单控制器(或辅助控制器)可以 s.th.例如“warehouse.amount = warehouse.amount + order.amount_in”,只需用订单中的 fk_prodref 字符串填写仓库字段“fk_prodref”。

    我所做的:我只使用橙色外键设置了模型产品和订单,并且效果很好。我现在尝试整合仓库,更新也能正常工作。 我还验证了一些关于 3 表关联的 SO 问题,但它们处理“有很多:通过”(汽车有马达,马达有活塞,使用 car.pistons ...),这里不是这种情况(我相信)。

    一般来说,这是否是一个糟糕的设计,只使用外键,而不使用与“id”相关的外键?我是否违反了“Rails”原则?

【问题讨论】:

    标签: ruby-on-rails foreign-keys associations


    【解决方案1】:

    如果我理解正确的话,你需要的是产品和仓库之间的多对多关系,而不是一对多关系。一个仓库有很多产品,一个产品有很多仓库。

    在 Rails 中,这可以通过 has_many :through 关联来设置。有关其工作原理的更多详细信息,请参阅The Rails Guide。医师、患者和约会示例与您尝试的类似。

    看起来您的 Orders 表中也缺少 warehouse_id 字段。没有它,鉴于产品可以同时存储在许多不同的仓库中,因此不清楚订单从哪个仓库运往/从哪个仓库运出。

    要解决上述问题,您的关联应类似于以下内容:

    class Warehouse
        has_many :products, through: :inventories
        has_many :orders
    end
    
    #new table required here to join Warehouses to Products
    class Inventory
        belongs_to :warehouse
        belongs_to :product 
    end
    
    class Product
       has_many :orders
       has_many :warehouses, through: :inventories
    end
    
    class Order
       belongs_to :product
       belongs_to :warehouse
    end
    

    要完成上述工作,您需要将 warehouse_id 和 product_id 字段添加到上述新的 Inventories 表中,并将 warehouse_id 字段添加到您的 Orders 表中。

    您还应该从 Warehouses 表中删除 product_id 和 fk_prodref 字段,因为您不希望那里有 belongs_to :product 关联。

    关于你问的其他问题:

    1. 使用 productref 而不是 product_id 作为外键并不违反 Rails 原则。您可以使用 foreign_key 和 primary_key 选项设置您的关联

      class Order
          belongs_to :product, foreign_key: :fk_productref, primary_key: 
          :productref 
      end
      
    2. 您无需先创建仓库即可预先创建产品。当前设置错误的原因是您使用的是 belongs_to ,在最新版本的 rails 中默认需要它。如果你想让 belongs_to 关联可选,你需要添加 optional: true

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      相关资源
      最近更新 更多