A TL;DR update on this in case anyone else has similar issues. Short version - seriously consider congomongo, clutch etc.
Part 1 - The Past ========== After some thinking, I headed towards deftype, to provide a level of abstraction atop clojureql. Queries can be incrementally refined like this (REPL example from book namespace): (-> (where (= :id "blah")) (select ["title", "binding"]) (page 3)) and similar from within a model named namespace. More complicated cases can be dealt with like this say, for a search: (book/search {:keyword "beer"}) => (defmulti query-refine (fn [query [key val]] key)) (defmethod query-refine :keyword [query [_ keyword]] (where query (matches keyword))) (defn search [search] (reduce query-refine (all) search)) This would get "all" books as a ClojureQL query, then refine as appropriate. Each function would return a new value of my type (key functions like "all" and "where" bootstrap the type), until finally the type was consumed as a seq. The type at any point contained the refined query thus far, plus any metadata (a real map when I left it). The deftype implemented seq by deref-ing the ClojureQL query and returning the results. A function like "page" above refines the query (to set the limit and offset) and also adds it's own metadata to the type (a total function to fetch the total result count via another refined query). The pagination view code plucks it's total out later for display. The namespace functions were created in each model namespace via macro, so they hid the tiresome config of each "model". At this point I discovered clj_record, which was trying to solve similar aims, however I was totally onboard with composable ClojureQL queries at this point, and so only the namespace building caught my eye. Part 2 - The Present ============ It was actually working like a charm, showing promise if Active Record is what you absolutely need, but I've since been able to gain the possibility of changing data storage, and generally rebooting the app to a large degree! And so I've been hacking out some congomongo based code, which appears to give me far less impedance mismatch. From 32 tables, I've boiled it down to 6 collections. Many of the current tables are there to keep relationships that are ideally nested anyway, and some are for unused features I'll cull in the reboot, or push out to 3rd party platforms. There is only one collection so far where a single rarely-updated field might need to be stored redundantly, and I think that might disappear when the full-text search implementation changes to something like Lucene / Solr (redundancy desired there anyway). In my controllers I've gone back to pretty simple code, and have been striving to avoid nurturing much notion of model namespaces at all (keeping namespaces function based, not one-per-model based). Aside from the queries and associations, those namespaces dealt with validation (Valip), but I think by-field-name validation could work for me (my sector fields are always market sectors, my country fields always ISO based etc). Will see how that pans out, but I'm very pleasantly surprised thus far. So it was pretty cool when I saw Rich's Strangeloop presentation yesterday, as I've really felt like I've been battling this complexity demon recently. I do feel like I'm winning now though. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en