我正在构建一个应用程序,其中用户是Organisation
. 一个组织有很多List
s,而后者又拥有很多ListItem
s。
现在,我希望管理员用户能够根据他们所属的组织(或者更确切地说,在他们的列表所属的组织上)指定列表项上可用的属性,而无需接触任何代码。
到目前为止,在定义未绑定到数据库中特定列的属性时,我使用了document_serializable,这是一个漂亮的小 gem(基于virtus),它将虚拟属性序列化为 db 中的 JSONB 列。我喜欢这种方法,因为我获得了 virtus 的所有优点(类型、强制、验证等),并且因为数据最终位于 JSONB 列中,这意味着可以相对轻松地快速加载、索引和搜索.
在动态添加这些用户定义的属性时,我想继续使用这种方法。所以我想做类似的事情:
class ListItem < ApplicationRecord
belongs_to :list
delegate :organisation, to: :list
organisation.list_attributes.each do |a, t|
attribute a, t
end
end
WhereOrganisation#list_attributes
返回属性名称及其关联类型的用户定义哈希,例如,可能如下所示:
{
name: String,
age: Integer
}
正如您可能已经猜到的那样,这不起作用,因为organisation.list_attributes.each
实际上是在 的上下文中运行的ListItem
,它是 的实例Class
,并且Class
没有#organisation
方法。我希望以一种有意义的方式措辞1。
我试过使用after_initialize
,但在对象生命周期的那个时刻,#attribute
是由ActiveRecord::AttributeMethods::Read
而不是拥有的DocumentSerializable::ClassMethods
,所以这是一种完全不同的方法,我不知道我是否仍然可以访问我需要的那个,以及它是否甚至可以工作.
另一种选择是以某种明确的方式找到有问题的组织,Organisation#find
-style,但老实说,我不知道我应该在哪里存储必要的信息。
所以,我的问题:在实例化(初始化或加载2)记录时,有没有办法可以检索存储在其关系之一的数据库列中的哈希?或者我是否试图以一种完全被误导的方式来构建它,如果是这样,我应该怎么做呢?
1澄清一下,如果我像这样直接使用哈希:
class ListItem < ApplicationRecord
belongs_to :list
delegate :organisation, to: :list
{
name: String,
age: Integer
}.each do |a, t|
attribute a, t
end
end
它会起作用,我的问题只是在这个较早的时间点获得记录的关系。
2我的理解是,每当从数据库创建或加载该类型的记录时,Rails 都会运行模型的代码,这意味着每次发生这种情况时都会重新定义虚拟属性,这就是为什么我要问如何在这两种情况下执行此操作.