【问题标题】:Ruby Foreign Key Constraints in Database vs Model数据库与模型中的 Ruby 外键约束
【发布时间】:2020-01-22 03:35:55
【问题描述】:

我在 Rails 应用程序中有以下模型。此设置运行良好,因为通常当我想向供应商添加新的 VendorPromo 时,可用 Promos 视图中有一个下拉菜单可供选择。现在,我正在通过 API 启用新的 VendorPromos 的创建。但是,此当前设置将允许创建具有任何 promo_id 的 VendorPromo,即使它在 Promo 中不存在。我见过belongs_to :promo, foreign_key: :promo,我知道您也可以通过数据库添加外键约束。我想知道这两种方法之间的区别以及哪种方法更好?

编辑:我认识到应用程序约束与 DB 约束不同,但是当我在应用程序中应用约束时,即 belongs_to :promo, foreign_key: :promo 它实际上似乎根本没有强制执行约束。具体来说,我可以创建一个新的 VendorPromo,其 promo_id 为 13,即使 Promo 只有 1 到 8 之间的 ID。

class Vendor
  has_many :vendor_promos
end

class VendorPromo
  belongs_to :vendor
  belongs_to :promo
end

class Promo
end

【问题讨论】:

  • 外键约束帮助我们维护有效数据,也是帮助我们避免应用程序中出现意外 nil 值的另一种方式。期望应用程序逻辑单独提供相同级别的保护是不现实的。
  • 我认为 id 超出范围,除非您对其他属性进行存在验证,否则它会创建该记录。您可以在数据库和模型中放置空约束,以确保在没有其他属性的情况下无法创建模型。

标签: sql ruby-on-rails database activerecord foreign-keys


【解决方案1】:

belongs_to 方法中的 foreign_key 属性实际上并没有定义外键,它为 Rails 的内部指定了哪个字段保存外键。

Ruby on Rails 指南在这里警告您:https://guides.rubyonrails.org/association_basics.html#options-for-has-many-foreign-key

无论如何,Rails 都不会为您创建外键列。您需要将它们明确定义为迁移的一部分。

【讨论】:

    【解决方案2】:

    Juan Carlos 的回答是其中的一部分。确实,belongs_to 中的 foreign_key 属性不强制执行任何数据库或应用程序级别的外键。我正在寻找的是 belongs_to :promo, optional: false 标志实际上强制执行应用程序级外键。除了数据库级别的外键约束之外,该标志还解决了我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-21
      • 2011-04-30
      • 2013-12-17
      相关资源
      最近更新 更多