问题描述
作为 Rails 的新手,我有点惊讶 Rails 迁移/ActiveRecord 没有为 has_many
、has_one
和其他关系创建数据库级外键.通过对主题的搜索可以清楚地看出,这是轨道方式.
Being new to rails, I'm a little surprised that the rails migration/ActiveRecord does not create database level foreign keys for has_many
, has_one
and other relations. It is clear from searching on the topic, that this is the rails way.
我在Agile Web Development一书中找到了一个例子使用 Rails 4,它使用了第 110 页上的以下示例.
I hit upon an example in the book Agile Web Development with Rails 4 which uses the following example on page 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
正是程序员会忘记添加的那种东西.此外,在我看来,它需要更多的代码行,意味着更多的错误等等.
This example made me cringe because ensure_not_referenced_by_any_line_item
is exactly the kind of thing a programmer would forget to add. Also, in my opinion, it requires more lines of code meaning more bugs, etc.
我发现了这个 thread 在同一主题上已有超过五年的历史.我也注意到了外国人珍宝.
I've found this thread which is more than five years old on the same topic. I've also become aware of the Foreigner Gem.
我的问题是关于 Rails 的当前状况.是否支持数据库级外键?有没有其他选择,比如外国人宝石?我对 Sqlite3 和 MySQL 后端感兴趣.
My question is regarding the current state of affairs in rails. Are database level foreign keys supported yet? Are there other options like the Foreigner Gem? I'm interested in Sqlite3 and MySQL backends.
推荐答案
还有一个更简洁的解决方案
There is also a cleaner solution for this
has_many :line_items, :dependent =>:restrict # 引发 ActiveRecord::DeleteRestrictionError
这将引发一个您可以捕获的错误.
This will raise an error that you can catch.
在任何情况下,您都需要指定 dependent
选项以避免在您的数据库中留下孤儿.记住这些事情并在 Rails 中设置适当的条件是开发人员的责任.
In any case, you need to specify the dependent
option to avoid having orphans left in your database. It is the developers responsibility to remember these things and set the proper conditions in Rails.
has_many :line_items, :dependent =>:delete # 将删除所有子记录
我从未使用任何额外的 gem 来处理外键.
I never used any additional gems to deal with Foreign keys.
这篇关于通过数据库级外键维护数据库完整性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!