Skip to content

Instantly share code, notes, and snippets.

@thomasmulvaney
Last active July 7, 2016 17:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomasmulvaney/01f7d5ea50e4f6de9bcd22d31291cd22 to your computer and use it in GitHub Desktop.
Save thomasmulvaney/01f7d5ea50e4f6de9bcd22d31291cd22 to your computer and use it in GitHub Desktop.
om normalisation issue
(ns example.core
(:require [om.next :as om :refer-macros [defui]]))
(def init-state
{:posts [{:post/id 0
:post/title "Foo"
:post/comments [{:comment/id 1}]}
{:post/id 1
:post/title "Bar"
:post/comments [{:comment/id 2}
{:comment/id 3}]}]
:comments [{:comment/id 1 :comment/body "sarcastic remark"}
{:comment/id 2 :comment/body "don't feed the troll"}
{:comment/id 3 :comment/body "..."}]})
(defmulti read om/dispatch)
(defmethod read :comments
[{:keys [state parser query] :as env} k params]
(let [st @state]
{:value (om/db->tree query (get st k) st)}))
(defmethod read :posts
[{:keys [state parser query] :as env} k params]
(let [st @state]
(println (pr-str @state))
{:value (om/db->tree query (get st k) st)}))
(defui Comment
static om/Ident
(ident [this {:keys [comment/id]}]
[:comments/by-id id])
static om/IQuery
(query [this]
'[:comment/body]))
(defui Post
static om/Ident
(ident [this {:keys [post/id]}]
[:posts/by-id id])
static om/IQuery
(query [this]
`[:post/title {:post/comments ~(om/get-query Comment)}]))
(defui BadRoot
static om/IQuery
(query [this]
`[{:posts ~(om/get-query Post)}]))
(defui GoodRoot
static om/IQuery
(query [this]
`[{:posts ~(om/get-query Post)}
{:comments ~(om/get-query Comment)}]))
;; With out the comment query, the comments are not properly normalised.
;; (om/tree->db BadRoot init-state true)
(comment
{:posts [[:posts/by-id 0] [:posts/by-id 1]],
:comments
[{:comment/id 1, :comment/body "sarcastic remark"}
{:comment/id 2, :comment/body "don't feed the troll"}
{:comment/id 3, :comment/body "..."}],
:comments/by-id
{1 {:comment/id 1}, 2 {:comment/id 2}, 3 {:comment/id 3}},
:posts/by-id
{0
{:post/id 0,
:post/title "Foo",
:post/comments [[:comments/by-id 1]]},
1
{:post/id 1,
:post/title "Bar",
:post/comments [[:comments/by-id 2] [:comments/by-id 3]]}},
:om.next/tables #{:comments/by-id :posts/by-id}})
;; Desired normalised state (after adding {:comments ...} query to root)
;; (om/tree->db GoodRoot init-state true)
(comment
{:posts [[:posts/by-id 0] [:posts/by-id 1]],
:comments
[[:comments/by-id 1] [:comments/by-id 2] [:comments/by-id 3]],
:comments/by-id
{1 {:comment/id 1, :comment/body "sarcastic remark"},
2 {:comment/id 2, :comment/body "don't feed the troll"},
3 {:comment/id 3, :comment/body "..."}},
:posts/by-id
{0
{:post/id 0,
:post/title "Foo",
:post/comments [[:comments/by-id 1]]},
1
{:post/id 1,
:post/title "Bar",
:post/comments [[:comments/by-id 2] [:comments/by-id 3]]}},
:om.next/tables #{:comments/by-id :posts/by-id}})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment