Rails 中具有相同键的两个表而不是 has_one 关系

Posted

技术标签:

【中文标题】Rails 中具有相同键的两个表而不是 has_one 关系【英文标题】:Two tables with same key in Rails instead of has_one relationship 【发布时间】:2011-10-30 22:11:23 【问题描述】:

我正在开发 Rail webapp。我有两个模型,用户,其中包含非常基本的信息:id、用户名和密码,以及配置文件,其中包括每个用户的配置文件。 (主要原因是有一个轻量级的用户模型,它将被定期调用,以及一个成熟的配置文件,将被不定期地调用)。这些模型中的每一个都有许多孩子。

现在,我的 Profile 有自己的主键,然后是外键 user_id 与 User 匹配。

但是,我想知道我是否应该让 Profile 模型与 User 模型具有相同的键(即 Profile.id == User.id 如果记录引用同一用户)。这很方便,因为当我有一个属于 User 的对象时,我希望它属于 Profile,反之亦然。例如,我可以指定 User has_many 和 Spec has_many 与 ChildModel 的关系。因为它们使用相同的键,所以我不必将 ChildModel 合并到 Spec,然后将 Profile 合并到 User 以找出与子对象关联的用户。

缺点是将来,如果由于某种原因我的用户主键和规范之间存在差异,那么我就有很大的麻烦了。

您对这种情况有什么建议?

谢谢。

【问题讨论】:

在您上面的问题中,Profile 和 Spec 实际上是同一个模型吗?换句话说,你有四个模型——Profile、User、Spec 和 Child——还是只有三个模型——Profile、User 和 Child? 是的。我更正了我的问题中的示例。此外,Profile 和 User 具有一对一的关系。我只将它们分成两个模型进行轻载。​​span> 【参考方案1】:

听起来您应该在ProfileUser 之间使用一对一的关系。您可以使用 has_onebelongs_to 声明来创建它。

class User < ActiveRecord::Base
  has_one :profile
end

class Profile < ActiveRecord::Base
  belongs_to :user
end

使用 Rails 进行敏捷 Web 开发第四版中所述:

这里说明了一条重要规则:包含外键总是的表的模型具有belongs_to 声明。

【讨论】:

Rails 约定是使用模型名作为单数形式,而数据库表是复数形式 @MBO:你是对的。我是倒着想的。谢谢。 嗨,马修,这就是我现在正在做的事情。但是,这种方法的缺点是:当我有属于 Profile 的 Children 并且我需要找出与 Child 对象关联的用户时,我需要先与 Profile 合并,然后再获取 User。它需要一个额外的合并步骤(这两个表很大,成本很高)。由于其他约束(例如表单等),我无法将 Children 类分配给 User 【参考方案2】:

我建议您使用 has_one 关系映射,如下所示

用户类

class User
  has_one :profile, :dependent => :destroy # you probably want this on destroy
end

迁移

create_table :users do |t|
   t.string :username
   t.string :password
end
create_table :profiles do |t|
   t. integer :user_id 
    ... other attributes
end

【讨论】:

以上是关于Rails 中具有相同键的两个表而不是 has_one 关系的主要内容,如果未能解决你的问题,请参考以下文章

反应警告:flattenChildren(...):遇到两个具有相同键的孩子,`.$index`

React组件中两个具有相同键的孩子

警告:flattenChildren (...) 遇到两个具有相同键的孩子 - 反应原生

有没有办法合并两个具有相同键的 JS 对象? [复制]

防止将具有相同 byte[] 键的两个项目添加到 KeyedCollection<byte[], MyObject>

在多重映射中,当两个迭代器保存具有映射到不同 Value 的相同键的值时。我们如何才能在地图中找到它们中的哪一个在另一个之前