【问题标题】:RoR: "belongs_to_many"? Association headacheRoR:“belongs_to_many”?协会头痛
【发布时间】:2009-11-13 23:03:14
【问题描述】:

我似乎无法解决这个问题,所以我想我会发帖看看是否有人可以帮助我(如果这个问题简单到令人发指,请原谅这个问题:现在对我来说很复杂!)

我有这些模型:

order
service
customer

我认为他们不言自明:servicecustomer 在放置 order 时购买的东西。

好的。

所以,我自然而然地建立了这些关系:

# a customer can have many orders
class Customer
   has_many :orders
end

# an order belongs to a single customer and can have many services
class Order
   belongs_to :customer
   has_many :services
end

...但这是我绊倒的地方:

# a service can belong to many orders
class Service
   # belongs_to :order ???
end

因为我对belongs_to 的理解是——如果我把它放在那里——一个服务只能属于一个order(它在order_id 键字段中只有一个值——目前不存在--将它绑定到一个订单,它需要能够属于许多订单)。

我在这里错过了什么?

【问题讨论】:

    标签: ruby-on-rails activerecord logic associations


    【解决方案1】:

    有两种方法可以处理这个问题。第一个是 Rails 管理的多对多关系。在这种情况下,您在 Order 和 Service 模型中都使用了“has_and_belongs_to_many”关系。 Rails 将自动创建一个管理关系的连接表。关系如下所示:

    class Order
      has_and_belongs_to_many :services
    end
    
    class Service
      has_and_belongs_to_many :orders
    end
    

    第二种方式是通过中间模型自己管理连接表。在这种情况下,您可能有另一个名为“LineItem”的模型,它代表订单上下文中的服务。关系如下所示:

    class LineItem
      belongs_to :order
      belongs_to :service
    end
    
    class Order
      has_many :line_items
    end
    
    class Service
      has_many :line_items
    end
    

    我自己更喜欢第二个。可能只有我一个人,但当它明确时,我不会对正在发生的事情感到困惑。另外,如果我想为关系本身添加一些属性(比如在你的情况下可能是一个数量),我已经准备好了。

    【讨论】:

    • 啊,好吧...我怀疑这可能是一种习惯关系,但不确定。谢谢。
    • 请注意,您仍然需要在 HABTM 关系中自己创建连接表
    【解决方案2】:
    class Customer
       has_many :orders
    end
    
    class Service
       has_many :orders
    end
    
    class Order
       belongs_to :customer
       belongs_to :service
    end
    

    Order 应该有customer_idservice_id,因为它与两者之间是多对一的关系。

    【讨论】:

    • 等等——这不是说order只能有一个service吗?我需要一个order 来拥有许多services... ??
    • 哦,从你的问题中看不出来。在这种情况下,它实际上是一个教科书式的答案——这种确切的情况是 DHH 编写的使用 Rails 进行敏捷 Web 开发一书的基础。 Darryl 的第二个解决方案就是他们所做的。
    【解决方案3】:

    我认为this Railscast 会帮助你——基本上你有两个选择。您可以使用has_and_belongs_to_manyhas_many :through

    您还会发现 has_and_belongs_to_many 已被弃用,取而代之的是 has_many :though => model_name,它提供了相同(甚至更多)的功能。

    【讨论】:

      【解决方案4】:

      我认为您已经意识到这一点,但您的订单实际上是一个复合域模型,有时在 DDD 中称为聚合。

      您的服务实际上是某人可以订购的某些产品/服务的列表。您的订单汇总记录了某人订购的内容。

      正如其他人所说,聚合由一个标题组成,即订单,其中包括订购者、日期、是否包括税金、运费等。订单包含多个 OrderLineItem。 OrderLineItem 属于_to 服务,包含订购数量、属于产品/服务等内容。

      类客户

      类顺序

      类 OrderLineItem

      我个人使用 OrderLineItem 模型名称来尊重 LineItem,因为在需要运送真实产品而不是服务的系统中,您可能有将订单链接到库存的分配,这些库存将具有获得分配的订单项和装运给客户的产品,其中也有行项目。因此,订单项术语可能会变得非常过载。在您的模型中可能不是这种情况,因为您只是在做服务。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-29
        • 1970-01-01
        • 1970-01-01
        • 2010-11-08
        • 2012-09-07
        • 2015-09-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多