如何正确关联rails中的对象而不为相关性制作单独的表

Posted

技术标签:

【中文标题】如何正确关联rails中的对象而不为相关性制作单独的表【英文标题】:How do I to properly relate objects in rails with out making separate tables for correlations 【发布时间】:2018-11-14 02:58:13 【问题描述】:

我想弄清楚如何减少我的 rails 应用程序中的表/对象的数量。这是几个对象及其关系的示例。到目前为止还没有数据,所以我可以根据需要编辑这些关系。对于此示例,有 3 个对象,用户、组和规则

用户 关系 belongs_to_and_has_many 组 belongs_to_and_has_many 规则

Groups 关系 #曾经有sub_groups belongs_to_and_has_many 组 belongs_to_and_has_many 用户 belongs_to_and_has_many 规则

Rules 关系 #曾经有sub_rules belongs_to_and_has_many 规则 belongs_to_and_has_many 群组 belongs_to_and_has_many 用户

要求: 我不想为每个关系都有表格。 用户可能没有任何组或规则,或者可能有不同的规则,具体取决于组。 一个组可能没有任何规则,也可能有多个规则。 规则可能只是组、用户或两者的一部分。 问题:

如何在一个规则对象的组字段中存储多个组? 我不想为每个关系都有一个单独的关系表,因为我们的系统有 30 个表,其中有很多不同的关系场景。应该有一种方法可以将关系存储在一个数组中,我以前从未有过这种方法,并且在历史上总是为这些关系创建单独的表/对象。 我是否将关系创建并存储为数组? Rails 会知道如何从那里添加/删除,还是会更多地在 GUI 上删除/编辑并在保存时保存新的对象数组?

【问题讨论】:

鉴于您已确定的要求,第一步可能是让规则使用与“主题”的多态关系,“主题”可以是组或用户。 减少表/对象的数量并不总是一个好主意。最好让正确的部分做好一项工作,然后将所有内容都塞进一小组上帝对象中。如果您从“拥有太多类很难 - 哇”的心态来设计您的应用程序,而不是实际查看需求和 SRP 以及如何使其可扩展,那么您做错了。 【参考方案1】:

是的,我也不想创建一大堆多对多表。所以,这就是我的做法(大致)。

我创建了一个名为“HasA”的类,类似于:

# == Schema Information
#
# Table name: has_as
#
#  id              :integer          not null, primary key
#  haser_type      :string           not null
#  haser_id        :integer          not null
#  hased_type:     :string           not null
#  hased_id:       :integer          not null
#  created_at      :datetime         not null
#  updated_at      :datetime         not null
#
class HasA < ActiveRecord::Base
  validates :haser_type, :haser_id, :hased_type, :hased_id, presence: true
  belongs_to :hased, polymorphic: true
  belongs_to :haser, polymorphic: true
end

然后我创建了一个模块(实际上是模块的集合),让我可以执行以下操作:

class User < ActiveRecord::Base
  acts_as_having :groups, :rules
end

还有

class Rule < ActiveRecord::Base
  acts_as_had_by :groups, :users
end

这样我就可以做这样的事情:

@user.groups            
@user.groups << @group  
@user.groups.destroy(@group)
@user.group_ids
@user.groups.where(id: 4)
@user.groups.new(id: 5, name: 'foo')

等等(基本上复制了has_many提供的许多标准方法)。

我也可以:

@rule.groups
@rule.users

现在,我可以关联任何我想要的模型,而不必拥有唯一的关联表。只有一个HasA 表关联所有内容。而且我可以对关联的记录进行各种操作,而无需编写任何额外的代码。我认为,这正是您要寻找的。​​p>

当然,我将它全部捆绑为一个 gem,以便我可以将它包含在我的所有项目中。因为谁愿意多次编写代码?

【讨论】:

出于好奇,你在 has_a 表上的索引是什么样的? 在迁移过程中,我做了类似的事情:add_index :haseds, [:hased_type, :hased_id] 和类似的hasers

以上是关于如何正确关联rails中的对象而不为相关性制作单独的表的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 4 中为多对多关联制作带有子表单的表单?

如何正确销毁 ruby​​ on rails 中的关联记录?

如何更改共享脚本中的变量,而不影响共享该脚本的所有其他游戏对象?

如何根据 Rails 中的其他对象验证多对多关联?

如何制作一个所有字段都是公共的公共结构而不为每个字段重复“pub”?

为啥 Ruby on Rails 不使用 .includes() 加载我的关联对象?