即使基数/一,枚举类型也不会被覆盖

时间:2015-03-22 23:06:41

标签: clojure enums datomic

在编写评分系统时,我希望人们能够对帖子进行评分,但我只希望每个用户有一个评分。

所以在我的架构中我有类似

的东西
{:db/id #db/id[:db.part/db -1] 
 :db/ident :rating/value
 :db/valueType :db.type/ref
 :db/cardinality :db.cardinality/one  <<thinking this serves a purpose
 :db/doc "rating applied to this particular post"
 :db.install/_attribute :db.part/db}

{:db/id #db/id[:db.part/user -2] 
 :db/ident :rating.value/verypositive}

{:db/id #db/id[:db.part/user -3]
 :db/ident :rating.value/positive}

{:db/id #db/id[:db.part/user -4]
 :db/ident :rating.value/needswork}

我只希望随时可以在每封电子邮件中获得一个评级,但我有点难过。

当我向帖子提交多个评分时

>(add-rating-to-post 1759 "so@gm.co" "verypositive")
>(add-rating-to-post 1759 "so@gm.co" "needswork")
>(add-rating-to-post 1759 "so@gm.co" "positive")
>(add-rating-to-post 1759 "so@gm.co" "verypositive")

交易运作正常,但当我查询附加到特定帖子后的评级时,我会得到类似的内容

({:bid 1759,
  :rating :rating.value/verypositive
  :email "sova@web"}
 {:bid 1759,
  :rating :rating.value/positive,
  :email "sova@web"}
 {:bid 1759,
  :rating :rating.value/needswork,
  :email "sova@web"})

真的,我想要的只是最新的一个,所以用户提交的所有评分的返回列表(最后的x)都会很棒。

...但是它会填充,直到每个枚举类型中都有一个,然后忽略添加。

关于如何实现我正在努力的行为的任何建议?

非常感谢提前

2 个答案:

答案 0 :(得分:1)

您的架构目前基本上说的是,每个rating.value只允许一个

我建议每位用户使用“单一评分”&#39;不应该是架构约束,而是域级问题 - 实现此问题的适当方法是允许每个用户每个帖子多个评级,然后编写一个transactor函数来检查用户是否有之前评了一个帖子,并再次拒绝评级,或者撤消旧评级(取决于您想要的行为)。

如果您还没有这样做,您还希望将评级本身视为一个实体。这样您就拥有:rating/post :ref:rating/value :ref:rating/email属性,并为每个评级创建一个新实体。

答案 1 :(得分:1)

您的架构是正确的。您使用ident进行枚举是正确的。

不是每次都创建一个新的评级实体,而是使用查询检查是否已有评分为:bid且评分为:email的用户。如果是这样,请使用:rating断言处理新的:db/add属性(不要担心撤消,它们是为:cardinality/one属性隐式创建的)。如果没有,请创建一个像您已经在做的那样。

如果你需要原子地做,e。 G。为了避免同一用户在竞争条件下在一篇文章上创建两个评级实体,您需要通过编写和使用database function.

来在交易者中完成所有这些工作。

如果您需要查看用户提供的所有评分,请使用history database等功能查询实体:rating值的变化情况。