即使 cardinality/one 枚举类型也不会覆盖
enumerated types not overwriting even though cardinality/one
在编写评级系统时,我希望人们能够对 post 进行评级,但我只希望每个用户有一个评级。
所以在我的模式中我有类似的东西
{: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}
我只希望每封电子邮件在任何时候都可以访问一个评级,但我有点难过。
当我向 post
提交多个评分时
>(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")
交易工作正常,但当我查询附加到特定 post-eid 的评级时,我得到类似
的信息
({: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 个)会很棒。
...但它会填充,直到每个枚举类型都有一个,然后忽略添加。
关于我如何实现我所追求的行为有什么建议吗?
非常感谢
你的架构目前基本上是说你只允许一个值 per rating.value
我建议 'single rating per user' 不应是架构约束,而应是域级问题 - 实现此问题的适当方法是允许 多个评级 每个 post 每个用户,然后编写一个交易函数来检查用户之前是否评价过 post 并且再次 deny 评价,或者 收回旧评级(取决于你想要的行为)。
您还希望将评级本身视为一个实体,如果您还没有这样做的话。这样您就拥有 :rating/post :ref
、:rating/value :ref
和 :rating/email
属性,并为每个评分创建一个新实体。
您的架构是正确的。您使用 idents 进行枚举是正确的。
不是每次都创建一个新的评级实体,而是使用查询来检查是否已经有一个具有评级 :bid
和评级用户 :email
的实体。如果是这样,请使用 :db/add
断言处理新的 :rating
属性(不要担心撤回,它们是为 :cardinality/one
属性隐式创建的)。如果没有,请像您已经在做的那样创建一个。
如果您需要自动执行,例如。 G。为了避免同一用户在竞争条件下对一篇文章创建两个评级实体,您需要通过编写和使用 database function.
在事务处理程序中完成所有这些工作
如果您需要查看用户给出的所有评分,请使用 history database 等功能查询实体的 :rating
值如何随时间变化。
在编写评级系统时,我希望人们能够对 post 进行评级,但我只希望每个用户有一个评级。
所以在我的模式中我有类似的东西
{: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}
我只希望每封电子邮件在任何时候都可以访问一个评级,但我有点难过。
当我向 post
提交多个评分时>(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")
交易工作正常,但当我查询附加到特定 post-eid 的评级时,我得到类似
的信息({: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 个)会很棒。
...但它会填充,直到每个枚举类型都有一个,然后忽略添加。
关于我如何实现我所追求的行为有什么建议吗?
非常感谢
你的架构目前基本上是说你只允许一个值 per rating.value
我建议 'single rating per user' 不应是架构约束,而应是域级问题 - 实现此问题的适当方法是允许 多个评级 每个 post 每个用户,然后编写一个交易函数来检查用户之前是否评价过 post 并且再次 deny 评价,或者 收回旧评级(取决于你想要的行为)。
您还希望将评级本身视为一个实体,如果您还没有这样做的话。这样您就拥有 :rating/post :ref
、:rating/value :ref
和 :rating/email
属性,并为每个评分创建一个新实体。
您的架构是正确的。您使用 idents 进行枚举是正确的。
不是每次都创建一个新的评级实体,而是使用查询来检查是否已经有一个具有评级 :bid
和评级用户 :email
的实体。如果是这样,请使用 :db/add
断言处理新的 :rating
属性(不要担心撤回,它们是为 :cardinality/one
属性隐式创建的)。如果没有,请像您已经在做的那样创建一个。
如果您需要自动执行,例如。 G。为了避免同一用户在竞争条件下对一篇文章创建两个评级实体,您需要通过编写和使用 database function.
在事务处理程序中完成所有这些工作如果您需要查看用户给出的所有评分,请使用 history database 等功能查询实体的 :rating
值如何随时间变化。