ruby-on-rails - 寻求帮助以防止添加包含太多列的表
问题描述
在我的应用程序中Post
,我有一个名为 的模型,它与Blog
. 这就是他们的样子:
app/models/post
:
class Post < ApplicationRecord
belongs_to :blog
end
app/models/blog
:
class Blog < ApplicationRecord
has_many :posts
end
该应用程序将收集和存储许多内容管理系统(如 Wordpress)的帖子,并且有些列应该只存在于某些类型的帖子中。我想知道是否有可能有某种层次结构,如下所示:
Post
- WordpressPost
- DrupalPost
这很重要,因为这些列应该只在它是 a 时才存在WordpressPost
,例如。
我试图理解一种叫做多态关联的东西(我真的做到了),但我就是无法理解这个概念,而且我也不确定这是否会给我带来这种灵活性。
现在posts
表格看起来像这样:
+------------+---------------------------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------------------------------------------------------------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| site_id | bigint(20) | NO | MUL | NULL | |
| status | enum('auto_draft','draft','future','pending','private','publish','trash') | NO | | NULL | |
| date | datetime | NO | | NULL | |
| title | varchar(255) | NO | | NULL | |
| url | varchar(255) | NO | | NULL | |
| body | longtext | NO | | NULL | |
| created_at | datetime(6) | NO | | NULL | |
| updated_at | datetime(6) | NO | | NULL | |
+------------+---------------------------------------------------------------------------+------+-----+---------+----------------+
但是像:
- status
- date
应该只存在于 Wordpress 帖子中。我真的很想了解做我想做的事的最佳方式。
谢谢你。
解决方案
在将 OO 继承映射到关系数据库时,我们通常有三种方法(如此链接中突出显示的):
- 单表继承(STI):一张表,包含所有子类使用的所有属性。这种方式更适合属性从一个子类到另一个子类变化不大的情况。
- 类表继承(MTI):一个具有公共属性的父表,每个子类的子表具有其特定属性和父表的外键。当每个子类甚至不同的关联之间有许多不同的属性时很好。
- 具体表继承:每个类一个表,包含所有需要的属性。如果有很少的共同属性可能会很好。
Rails 允许我们创建单表继承(STI),我们也可以使用具体表继承。但是它没有内置的方式来处理类表继承(以及多表继承 - MTI),这并不妨碍你创建自己的方式,就像它在这个发布。
Rails 还允许我们拥有一个多态关联,当我们想要为某些记录关联一种类型而为其他记录关联另一种类型时,这很有用,这可以用于继承,但实际上并不是为此而设计的。在此链接中,您将找到所有三种类型的示例以及如何使用它们。
实现它的另一种方法是拥有一个options jsonb field
. 当您的字段因一条记录而异时,这是一种很好的方法。这是一种更简单的方法,但必须精心设计,因为可能有一些缺点。
建议的解决方案:
我不会使用:
- STI:正如您所说,这将是许多不同的管理系统,我认为这不是一个好主意,因为您将有太多未使用的列。
- Concrete Table Inheritance:我想您希望在进行过程中轻松添加新的管理系统,将它们视为一个系统并忽略它们的细微差别。所以这不是一个好的选择,因为这会使理解它们的共性变得更加困难。
我可以使用:
- MTI:这将是一个很好的数据库设计,但是当您使用 Rails 时,您必须以自己的方式处理它,这可能会给代码增加一些复杂性。如果我更关心拥有标准化数据库,我会使用它。
- 多态关联:与MTI相比,会给数据库增加一些复杂性,并且使其可用作继承也会给代码增加一些复杂性。我更喜欢将它与实际的多态关联一起使用。
我会使用:
- 一个选项 json 字段:我相信您将需要在某些特定时刻访问此特定属性,并且每个不同的管理系统都不会有其他关联。因此,我想这将是最直接的解决方案,同时受到 rails 和数据库的完全支持,而不会增加两者的复杂性。
Ps:如果你只有一些不同的属性,我会用 STI 代替。
推荐阅读
- google-app-engine - 如何将 Google App Engine 配置为不构建某些 Go 文件?
- eclipse - spring boot 在eclipse中和构建后都使用文件路径
- redux - 如何使用 reduxThunk 应用 redux 开发者工具
- python - Python OOP - 从不同文件导入类
- php - 从 var_dump(JSON) 回显 PHP 例如 [''address"] 和 ["network"]
- javascript - Javascript,针对父元素:为什么没有触发事件?
- docker - docker compose cli 命令中的 2>&1 是什么意思?
- r - rshiny主面板pdf输出
- php - Composer PHPSpreadsheet 为 gd 扩展提供错误,即使它已启用
- javascript - 如何清除我函数中的计时器?