通过数据库级​​外键维护数据库完整性

时间:2014-07-04 12:23:58

标签: ruby-on-rails ruby-on-rails-4

作为rails的新手,我很惊讶rails migration / ActiveRecord不会为has_manyhas_one和其他关系创建数据库级外键。从搜索主题可以清楚地看出,这是轨道方式。

我在书Agile Web Development with Rails 4中找到了一个例子,它使用了第110页的以下示例。

class Product < ActiveRecord::Base
  has_many :line_items
  before_destroy :ensure_not_referenced_by_any_line_item
  ...
  private

    # ensure that there are no line items referencing this product
    def ensure_not_referenced_by_any_line_item
      if line_items.empty?
        return true
      else
        errors.add(:base, 'Line Items present')
        return false
      end
    end
end

这个例子让我感到畏缩,因为ensure_not_referenced_by_any_line_item正是程序员忘记添加的那种东西。此外,在我看来,它需要更多的代码行,意味着更多的错误等。

我发现这个thread在同一主题上已超过五年了。我也了解Foreigner Gem

我的问题是关于铁轨的现状。是否支持数据库级外键?还有其他选项,如Foreigner Gem?我对Sqlite3和MySQL后端感兴趣。

1 个答案:

答案 0 :(得分:0)

还有一个更清洁的解决方案

has_many :line_items, :dependent => :restrict # raises ActiveRecord::DeleteRestrictionError

这会引发您可以捕获的错误。

在任何情况下,您都需要指定dependent选项以避免在数据库中留下孤儿。开发人员有责任记住这些事情并在Rails中设置适当的条件。

has_many :line_items, :dependent => :delete # Will remove all child records

我从未使用过任何额外的宝石来处理外键。