Rails与多个外键和数据库约束的多态关联

时间:2014-12-07 14:58:54

标签: ruby-on-rails postgresql ruby-on-rails-4 polymorphic-associations multi-table-inheritance

我一直在玩多表继承和数据库约束。我知道Rails哲学是处理代码中的约束而不是数据库中的约束,但我想两者兼顾。我也知道多态关联,但它们不允许你强制执行约束。

所以这是我的方案,而不是guides中的imageable_typeimageable_id,我希望employee_idproduct_id(在我的情况下,我将只有两个外键)。这让我可以创建一个像解释here一样的约束。

但是现在,我有一个问题,我需要创建一个条件关系,rails似乎没有为此提供任何东西。我需要一个imageable关系,该关系可以链接到产品或员工,具体取决于填写的字段。

有任何建议如何在Rails中这样做?我知道如何在SQL中执行约束,我的问题是如何在Rails中实现这种多态关系。

再一次,我知道如何在没有数据库约束的情况下做到这一点,但数据库约束是我的问题的重点:)

1 个答案:

答案 0 :(得分:1)

假设您最多允许 1 引用employeeproduct

CREATE TABLE picture (
  picture_id serial PRIMARY KEY
, picture text NOT NULL
, employee_id int REFERENCES employee
, product_id int REFERENCES product
, CONSTRAINT employee_xor_picture
       CHECK (employee_id IS NULL OR product_id IS NULL)
);
  • employee_idproduct_id每个reference各个表的PK,可以为NULL。
  • CHECK constraint employee_xor_picture强制执行其中至少有一个始终为NULL。

强制执行其中之一是NOT NULL - 它通常更方便地允许尚未分配的图片,但这实际上取决于您的要求。为了强制执行这一点:

    CHECK (employee_id IS NULL AND product_id  IS NOT NULL OR
           product_id  IS NULL AND employee_id IS NOT NULL)