如何在Rails应用程序中设置复合主键

6

我在我的应用程序中使用 'foriegner' gem 来设置主键,现在我遇到了一个需要在表中设置复合主键的情况。

我在网上搜索了这个问题,但是没有找到清晰的解决方案。

请告诉我是否可以使用 foreigner gem 或其他方法在 Rails 应用程序中设置复合键。

注意:我正在使用 Postgres

谢谢。


1
  1. 你确定你需要它们吗?
  2. 如果是的话,你确定Rails是你的应用程序的正确选择吗? 据我所知:Rails和复合键根本不兼容,使用它们会违背Rails的理念。因此,如果你要使用它们,你将经常与框架作斗争。
- Alexander Günther
1
是的,我确定我需要使用复合键。 因此,在Rails中不应使用复合键...如果我们确实使用它, 会出现一些问题吗? - balanv
1
问题在于你将会错过很多“Rails Magic”,并且需要做很多额外的工作,比如在迁移中编写 SQL 代码,这将使其与特定的数据库绑定... 其他框架可能会为这些特殊情况提供更好的支持。 - Alexander Günther
1
好的,我应该放弃使用复合键的想法吗? - balanv
你要做什么是你的决定。我认为你应该意识到你的决定所带来的后果。例如,如果你选择在ActiveRecord模型上使用Composite Keys,那么Rails中的*_book_path帮助程序将无法立即使用。你的迁移需要更多的工作……但是,如果你不使用Composite Keys,可能会遇到更大的问题。我不知道你的情况如何,你需要在做决定之前先考虑是否明智。 - Alexander Günther
2个回答

2

ActiveRecord

有一个名为 composite_primary_keys 的宝石,可以很好地集成这些功能到 ActiveRecord 中。

它支持 各种版本的 ActiveRecord

# Gemfile
gem 'composite_primary_keys', '=<version for your AR version>'

请按照以下示例使用:

class Membership < ActiveRecord::Base
  self.primary_keys = :user_id, :group_id
end

membership = Membership.find([1,1])  # composite ids returns single instance
# => <Membership:0x39218b0 @attributes={"user_id"=>"1", "group_id"=>"1"}>

我很高兴地在生产中使用它,使我的模式保持干净整洁。

更好的选择:Sequel

一如既往,如果您正在寻找一个伟大的Ruby + PostgreSQL解决方案,那么就不要再看了,直接去看 jeremyevans/sequel

它拥有大量功能,包括复合主键。开箱即用。

因此,如果您要启动一个新项目(显然是在PostgreSQL上),请避免ActiveRecord的麻烦,转而使用Sequel。

class Post < Sequel::Model
  set_primary_key [:category, :title]
end

1
简短回答:在Rails中不要使用复合主键(除非因为遗留数据库而被迫这样做)。
虽然可能有适用的gem解决方案(目前),但这不是ActiveRecord的工作方式。我也不会在Rails之外使用复合主键,除非有一个非常好的理由。它们使许多事情变得更加复杂。
但是:你可以将你认为的复合主键作为备选键,并拥有Rails默认的PK(postgres:伪类型“serial”,它从序列中获取其值)。只需确保为构成你的键的那些列添加唯一索引即可。

使用复合主键有许多好处。这个答案是完全错误的,而且来自于一种防御性的 ActiveRecord 有限的观点。 - Overbryd
这就是我说的:在Rails中,除非有充分的理由。请详细说明...在什么情况下会使用复合键? - Pascal
@Overbryd 谢谢你提供的链接!不过我还是不同意 :-) 我认为这个答案对于 Rails 是有效的,无论你对 SQL 中复合主键的看法如何。虽然在 Rails 中对复合主键的支持不太理想,所以最好不要使用它。在我看来。 - Pascal
...而且有很多合理的理由。例如,处理已经存在的数据库中有大量复合主键的情况。因此,简单地强调“不要使用”并不是正确的方法... - Andre Figueiredo
好的,同意你的观点 +1 - Andre Figueiredo
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接