【问题标题】:Postgresql referential integrity constraints in Rails 3Rails 3 中的 Postgresql 引用完整性约束
【发布时间】:2012-05-30 08:11:04
【问题描述】:

遇到this 帖子,它说数据库处理的引用完整性根本不是 Rails 方式。

但是考虑一下:

class User < ActiveRecord::Base
  belongs_to :department
end

class Department < ActiveRecord::Base
  has_many :users
end

#User Model
id: integer, name: string,department_id: integer
#Department Model
id: integer, name: string

在这里我需要创建一个新用户并执行以下规则

  • 用户应该被分配到一个部门
  • users.department_id 应该匹配 departments.id
  • 如果users.department_iddepartments.id 不匹配,则不应创建记录并引发错误。

现在,我如何以 Rails 方式完成此任务?或者通过在迁移中删除原始 SQL 添加外键是唯一的方法?

【问题讨论】:

  • “Rails 方式”头脑简单、愚蠢,并且受制于竞争条件(除其他外)。如果您完全关心您的数据,您将在数据库中使用真正的 FK,foreigner 将帮助您解决此问题,直到 Rails 开发人员淡化态度以支持良好的感觉。
  • 是的,这看起来很奇怪,但是嘿,rails 是一个固执己见的软件 :)
  • 但是他们的逻辑存在漏洞,他们让自己的态度妨碍了可靠的软件。至少他们承认他们的方法在Validations Guide 中存在唯一性的缺点。我已经见过足够多的不可能事情了,而且我至少和 Rails 一样固执己见 :)
  • 在阅读了 DHH 的报价后,我永远不会猜到他在谈论参照完整性(是吗?),而是在谈论诸如数据库不保存订单之类的东西,因为总订单价值低于最小值阈值或类似的东西。无论如何,@muistooshort 当然是对的 :)
  • @DanielRikowski: 外键 is 是一个约束,是数据库强制参照完整性的方式;默认情况下,Rails 不知道真正的 FK 是什么,所以我认为 DHH 是在谈论参照完整性(或者他可能只是对关系数据库了解得不够透彻,无法了解 FK)。数据完整性是数据库的工作,这就是为什么您使用一个而不是一堆平面文件的原因。我用 FK 和 CHECK 和触发器以及所有这些好东西加载我的数据库:修复代码中的错误很容易,数据库中的错误通常是永久性的。 IMO 当然,但我的意见是正确的 :)

标签: ruby-on-rails ruby-on-rails-3 postgresql database-design activerecord


【解决方案1】:

在 Rails 中,您只需将其添加到您的用户模型中:

validates_presence_of :department

Rails 将在允许保存操作之前检查有效的部门。如果您愿意,您也可以使用像外国人这样的 gem 将外键添加到您的表中。我通常这样做是因为我不可避免地发现自己有时需要直接批量加载数据。

【讨论】:

  • 我已经进行了此验证,但我正在验证 department_id 。将其更改为department & 现在可以使用了。但我想知道为什么它现在有效而之前没有?
  • 如果您要验证 ID 的存在,请确保填写了 ID 字段,但如果 ID 实际上引用了现有行,则不会。通过验证关联,您可以确保该 ID 引用了匹配的行。
【解决方案2】:

如果 Lukas 的回答不符合您的需求,您也可以在模型上使用 before/after save hooks

class User < ActiveRecord::Base

  before_save :validate_department

  def validate_department
     #validate the department
     #raise an error if invalid?
  end

end

【讨论】:

    猜你喜欢
    • 2012-01-31
    • 2012-07-11
    • 1970-01-01
    • 2015-04-11
    • 2020-01-14
    • 2022-01-23
    • 2015-11-03
    • 1970-01-01
    相关资源
    最近更新 更多