I''m starting work on our in-house CMS and I''ve hit a difficult problem. As far as storing the documents in the CMS and organizing them into a tree structure I have two options: a) Store all documents in a single table with meta-data columns and the actual document content in a serialized string, this however greatly limits searching/sorting or b) Store each model in it''s own table along with a belongs_to :meta entry for the meta data, this however reduces flexibility in terms of storing several types of documents in one tree node. It seems I will have to sacrifice one thing to get the other, so it would be nice if someone who''s had a similar problem could nudge me in the right direction (or a new one). -- SIMEN BREKKEN / this path leads to the gates of madness.
On 31/05/2005, at 6:41 PM, Simen Brekken wrote:> I''m starting work on our in-house CMS and I''ve hit a difficult > problem. As far as storing the documents in the CMS and organizing > them into a tree structure I have two options: a) Store all documents > in a single table with meta-data columns and the actual document > content in a serialized string, this however greatly limits > searching/sorting or b) Store each model in it''s own table along with > a belongs_to :meta entry for the meta data, this however reduces > flexibility in terms of storing several types of documents in one tree > node.How about having ''content nodes'' that define site tree, and having the tree-based content belong_to a content node? - tim lucas
>> I''m starting work on our in-house CMS and I''ve hit a difficult >> problem. As far as storing the documents in the CMS and organizing >> them into a tree structure I have two options: a) Store all documents >> in a single table with meta-data columns and the actual document >> content in a serialized string, this however greatly limits >> searching/sorting or b) Store each model in it''s own table along with >> a belongs_to :meta entry for the meta data, this however reduces >> flexibility in terms of storing several types of documents in one tree >> node. > >How about having ''content nodes'' that define site tree, and having the >tree-based content belong_to a content node? > >- tim lucasI''ve roughly modeled that approach with models: Meta (author, created_at, updated_at, parent_id) Document (mostly convenience methods) Article < Document Event < Document Download < Document However my problem always arises when I want to do: "Give me all documents under node 2", I''d have to select from quite a lot of tables to get both Articles, Events and Downloads. So I''m back to square one :) Suggestions highly welcome! -- SIMEN BREKKEN / this path leads to the gates of madness.
On 01/06/2005, at 5:37 AM, Simen Brekken wrote:> However my problem always arises when I want to do: > "Give me all documents under node 2", I''d have to select from quite a > lot of tables to get both Articles, Events and Downloads.You could add another level of indirection, by maintaining a table ''MetaDocuments'' with: id, meta_id, document_type, document_id You''d then have to collect all the doc''s of the same type and do finds on the arrays of ids for each type. - tim
I think this is how Muaveweb does this, I''m still unsure of how flexible it is though. Also if I have to perform three queries to retrieve a single document the system would be very slow. SIMEN BREKKEN / this path leads to the gates of madness. Tim Lucas wrote:> On 01/06/2005, at 5:37 AM, Simen Brekken wrote: > >> However my problem always arises when I want to do: >> "Give me all documents under node 2", I''d have to select from quite a >> lot of tables to get both Articles, Events and Downloads. > > > You could add another level of indirection, by maintaining a table > ''MetaDocuments'' with: > id, meta_id, document_type, document_id > > You''d then have to collect all the doc''s of the same type and do finds > on the arrays of ids for each type. > > - tim > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
> "Give me all documents under node 2", I''d have to select from quite a > lot of tables to get both Articles, Events and Downloads.You will definately want to look into the theory of nested sets. Maybe you can start by reading the documentation of #acts_as_nested_set http://api.rubyonrails.com/classes/ActiveRecord/Acts/NestedSet/ClassMethods.html Good luck Sascha
That was my original plan, to use nested set for the tree structure and attach content to nodes, so the real question isn''t how the tree should be made but how stuff should be attached to it. Sascha Ebach wrote:>> "Give me all documents under node 2", I''d have to select from quite a >> lot of tables to get both Articles, Events and Downloads. > > > You will definately want to look into the theory of nested sets. Maybe > you can start by reading the documentation of #acts_as_nested_set > > http://api.rubyonrails.com/classes/ActiveRecord/Acts/NestedSet/ClassMethods.html > > > Good luck > Sascha > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
On 01/06/2005, at 6:00 PM, Simen Brekken wrote:> Tim Lucas wrote: >> On 01/06/2005, at 5:37 AM, Simen Brekken wrote: >>> However my problem always arises when I want to do: >>> "Give me all documents under node 2", I''d have to select from quite >>> a lot of tables to get both Articles, Events and Downloads. >> >> You could add another level of indirection, by maintaining a table >> ''MetaDocuments'' with: >> id, meta_id, document_type, document_id >> >> You''d then have to collect all the doc''s of the same type and do >> finds on the arrays of ids for each type. > > I think this is how Muaveweb does this, I''m still unsure of how > flexible it is though. Also if I have to perform three queries to > retrieve a single document the system would be very slow.What do you mean by ''how flexible it is''? What flexiblity do you want, or what do you see as inflexible about this approach? Why would three queries be slow? Can you not use caching? - tim lucas
The most ideal approach would of course be to be able to store everything in the same table without the penalty of serialization but I guess that is somewhat hard to accomplish without an OODB, by flexibility I mean having to maintain three separate relations for each object. SIMEN BREKKEN / this path leads to the gates of madness. Tim Lucas wrote:> On 01/06/2005, at 6:00 PM, Simen Brekken wrote: > >> Tim Lucas wrote: >> >>> On 01/06/2005, at 5:37 AM, Simen Brekken wrote: >>> >>>> However my problem always arises when I want to do: >>>> "Give me all documents under node 2", I''d have to select from quite >>>> a lot of tables to get both Articles, Events and Downloads. >>> >>> >>> You could add another level of indirection, by maintaining a table >>> ''MetaDocuments'' with: >>> id, meta_id, document_type, document_id >>> >>> You''d then have to collect all the doc''s of the same type and do >>> finds on the arrays of ids for each type. >> >> >> I think this is how Muaveweb does this, I''m still unsure of how >> flexible it is though. Also if I have to perform three queries to >> retrieve a single document the system would be very slow. > > > What do you mean by ''how flexible it is''? What flexiblity do you want, > or what do you see as inflexible about this approach? > > Why would three queries be slow? Can you not use caching? > > - tim lucas > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
On 01/06/2005, at 9:26 PM, Simen Brekken wrote:> Tim Lucas wrote: >> On 01/06/2005, at 6:00 PM, Simen Brekken wrote: >>> I think this is how Muaveweb does this, I''m still unsure of how >>> flexible it is though. Also if I have to perform three queries to >>> retrieve a single document the system would be very slow. >> >> What do you mean by ''how flexible it is''? What flexiblity do you >> want, or what do you see as inflexible about this approach? >> >> Why would three queries be slow? Can you not use caching? > > The most ideal approach would of course be to be able to store > everything in the same table without the penalty of serialization but > I guess that is somewhat hard to accomplish without an OODB, by > flexibility I mean having to maintain three separate relations for > each object.Yeah it sucks i know... but i guess its the best you can do with the available tools, short of making the cms''s features less flexible. - tim
I''m using a twist on Tims suggestion: ''MetaDocuments'' with: id, meta_id, document_type, document_id Instead my approach works like this: ''MetaDocuments'' with: id, type (plus any other meta information you might want to use, whatever) I use single-table inheritance on this table, so a MetaDocuments will return one of MetaArticleDocument, MetaNewsPageDocument, MetaPhotoAlbumDocument, etc; for each new type of document you want to add, you create a special MetaSomekindofDocument which subclasses MetaDocuments. Now, each respective MetaSomekindofDocument has a has_one relationship, uniformly called :document to its respective SomekindofDocument. metadoc = MetaDocument.find(id) puts metadoc.type # "MetaSomekindofDocument" puts metadoc.document.type # "SomekindofDocument" Dont know if this gives you an ideas or helps you, just thought I might share. Best regards, Tomas Jogin On 6/1/05, Simen Brekken <simen-qaH4BmqzZooOvCyXmLEu7A@public.gmane.org> wrote:> I think this is how Muaveweb does this, I''m still unsure of how flexible > it is though. Also if I have to perform three queries to retrieve a > single document the system would be very slow. > > SIMEN BREKKEN / this path leads to the gates of madness. > > > > Tim Lucas wrote: > > > On 01/06/2005, at 5:37 AM, Simen Brekken wrote: > > > >> However my problem always arises when I want to do: > >> "Give me all documents under node 2", I''d have to select from quite a > >> lot of tables to get both Articles, Events and Downloads. > > > > > > You could add another level of indirection, by maintaining a table > > ''MetaDocuments'' with: > > id, meta_id, document_type, document_id > > > > You''d then have to collect all the doc''s of the same type and do finds > > on the arrays of ids for each type. > > > > - tim > > > > _______________________________________________ > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Funny that was what I just ended up after a while in the thinking box, thanks for sharing! SIMEN BREKKEN / this path leads to the gates of madness. Tomas Jogin wrote:>I''m using a twist on Tims suggestion: > >''MetaDocuments'' with: >id, meta_id, document_type, document_id > >Instead my approach works like this: > >''MetaDocuments'' with: >id, type (plus any other meta information you might want to use, whatever) > >I use single-table inheritance on this table, so a MetaDocuments will >return one of MetaArticleDocument, MetaNewsPageDocument, >MetaPhotoAlbumDocument, etc; for each new type of document you want to >add, you create a special MetaSomekindofDocument which subclasses >MetaDocuments. > >Now, each respective MetaSomekindofDocument has a has_one >relationship, uniformly called :document to its respective >SomekindofDocument. > >metadoc = MetaDocument.find(id) >puts metadoc.type # "MetaSomekindofDocument" >puts metadoc.document.type # "SomekindofDocument" > >Dont know if this gives you an ideas or helps you, just thought I might share. > >Best regards, >Tomas Jogin > >On 6/1/05, Simen Brekken <simen-qaH4BmqzZooOvCyXmLEu7A@public.gmane.org> wrote: > > >>I think this is how Muaveweb does this, I''m still unsure of how flexible >>it is though. Also if I have to perform three queries to retrieve a >>single document the system would be very slow. >> >>SIMEN BREKKEN / this path leads to the gates of madness. >> >> >> >>Tim Lucas wrote: >> >> >> >>>On 01/06/2005, at 5:37 AM, Simen Brekken wrote: >>> >>> >>> >>>>However my problem always arises when I want to do: >>>>"Give me all documents under node 2", I''d have to select from quite a >>>>lot of tables to get both Articles, Events and Downloads. >>>> >>>> >>>You could add another level of indirection, by maintaining a table >>>''MetaDocuments'' with: >>>id, meta_id, document_type, document_id >>> >>>You''d then have to collect all the doc''s of the same type and do finds >>>on the arrays of ids for each type. >>> >>>- tim >>> >>>_______________________________________________ >>>Rails mailing list >>>Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org >>>http://lists.rubyonrails.org/mailman/listinfo/rails >>> >>> >>> >>_______________________________________________ >>Rails mailing list >>Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org >>http://lists.rubyonrails.org/mailman/listinfo/rails >> >> >> >_______________________________________________ >Rails mailing list >Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org >http://lists.rubyonrails.org/mailman/listinfo/rails > > >