通常的做法是在 plugin_store_rows 表的 key 字段中同时存储命名空间和唯一标识符,即:
<namespace>_<id>
如今,在核心 Discourse 插件中,这种模式的使用频率有所下降,PluginStore 的整体使用率也在降低,例如:
-
OAuth2 Basic 插件 曾使用它来存储关联账户数据,直到我们将其迁移到 user_associated_accounts。
-
Poll 插件 在迁移到其专属表之前曾使用它。
不过,该模式仍被用于某些地方,包括核心 Discourse 代码库本身,例如 在 Reviewables 模型中。
我自己在多个插件中也使用了这种模式。
使用该模式的主要原因是,plugin_store_rows 表被多个插件(以及一些核心服务)共用,因此标识列(即 id 和 plugin_name)无法用于各个使用 PluginStore 的系统内部的识别。因此,key 列改用基于字符串的系统。
关于在插件内部更改数据库结构,@gdpelican 有一篇很好的帖子:
就我个人而言,我对这样做仍相当谨慎,因为作为第三方插件,你无法控制命名空间、无法控制插件是否会被移除,也无法控制核心 Discourse 可能做出的潜在冲突性更改。
正如 @gdpelican 提到的,你需要提供一种方式,让用户在卸载插件时能够清理数据库的更改。
为用户提供一种方法,以便在不再需要你的插件时清理你的数据库更改。我通过一个 rake 任务实现了这一点。
我觉得这对大多数插件用户来说过于琐碎,如果他们不了解这一细节,还存在风险。
此外,我尚未发现有必要超出 PluginStore 和 CustomFields 的范围。
话虽如此,就我个人而言,我支持在 PluginStore 中添加类似的新方法,因为我认为这种模式很有用。
@david,也想听听你对上述内容的看法。