基于用户首选项的动态表列

时间:2013-06-09 22:51:55

标签: ruby-on-rails-3 postgresql

方案

让我们说用户是推销员。 User模型有许多log_entries用作销售数据的每日日志。用户还具有允许他们选择在其log_entry表单中可见的字段的首选项。因此,如果他们选择菠萝,香蕉和葡萄......那些将是形式的领域。如果这些选择发生变化,数据就不会丢失......只是在表单中看不到。 现在,假设用户只是选择了蔓越莓销售帐户,但蔓越莓在用户偏好表单中不是可选择的属性。他们需要能够创建“类别”。现在,菠萝季节已经结束,所以他们登录到那里的首选项,取消选中菠萝盒并检查草莓盒。现在,当他们在他们的日志中输入数据时,会有一个草莓数据字段,但不是菠​​萝。菠萝数据没有消失......它只是没有显示出来。

这种情况会带来一些挑战。一个是作为开发人员我不提前知道数据库列名,因为用户可以动态创建新的“类别”(我可以要求用户联系我以根据需要添加更多,但是......)。并且,当用户创建新类别时... log_entries表将没有表示该新数据的列。

如何管理动态数据库列? postgres hstore可以处理这个吗?

一行是基于日期属于用户的条目。每列都包含特定于属性的数据(例如......一列可以标题为'草莓',它将保存那天销售的单位数量)

2 个答案:

答案 0 :(得分:4)

通常的做法是:

  • EAV
  • hstore
  • XML
  • JS​​ON

请参阅:

整个“将列提供给其他用户”只需要您保留每当用户定义以前未使用的密钥时添加的“自定义密钥”表。

首先使用动态DDL添加列听起来很合理,但是您可以存储的列数以及行的“宽”范围是有限的。随着您添加更多列,扫描表的性能会变差,尽管“稀疏”列(大多数是空的)相对便宜。添加一个列需要一个独占锁,这可能需要一些时间才能进入一个繁忙的系统,但如果它没有被定义为NOT NULL DEFAULT ...,那么添加它自己的列非常快。一开始它会很好用,但我怀疑你会后悔这样做。

答案 1 :(得分:0)

我最终没有使用hstore,因为我认为这不是最好的解决方案。它可能是......我只是不想投入时间和摸索找出它。我最终做的是改变我现有的偏好模型并创建一些新模型。在Preferences模型中,我有一个字符串列,我在其中存储引用模型的名称和模型项id ...然后在需要时对字符串进行constantized。

因此,如果用户想要在他们的偏好中包含水果,他们可以点击“添加更多水果”,如果他们想要的特定水果没有列出,他们可以添加它。当他们保存他们的偏好时,所选的水果ID将被存储为整数,并且通过隐藏字段,引用的模型(在本例中为“Fruit”)将被存储为字符串。

然后,在用户首选项索引页面中,我有一个标题为Fruit的部分(如果用户有任何Fruit首选项)。查询只是在Preference表中搜索匹配current_user的用户,匹配“Fruit”的modelref,并使用未关联的存储ID查找水果记录。

我可能没有那么好解释......但是,也许它会帮助其他人寻找类似的东西。