如何正确关联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 中的关联记录?
如何更改共享脚本中的变量,而不影响共享该脚本的所有其他游戏对象?