Search code examples
ruby-on-railsrubymongodbhstore

Model attribute contains collection of object


I have main model Page, which is container. The page can have some to-do lists, notes, files and discussions. The idea is to have them in special order.

Page.last.container # [Todolist_obj, Note_obj, File_obj, Note_obj, Discussion_obj, File_obj, File_obj] 
  • So I came to approach to use Mongodb

  • Or I also thought about using Postgres with hstore, but don't know will it help or not

  • Or maybe just any database and deserialize all objects when getting page, and serialize objects when saving

  • Or I can make superclass Item and inherit all containing objects from it using MTI and make Page has many relationship.

So I don't know which way is the best?

or perhaps there is a better way?


Solution

  • I have used acts_as_list for implementing sortable objects very successfully. Additionally, i would abstract the elements of a page into a separate model, here called PageElement.

    I think there is no need to switch to a NoSQL database (although i have nothing against this approach). Here is a rough sketch of what i'm thinking:

    class Page < ActiveRecord::Base
      has_many :page_elements, :order => 'position'
      has_many :todo_lists,  :through => :page_elements, :source => :element, :source_type => 'TodoList'
      has_many :notes,       :through => :page_elements, :source => :element, :source_type => 'Note'
      has_many :files,       :through => :page_elements, :source => :element, :source_type => 'File'
      has_many :discussions, :through => :page_elements, :source => :element, :source_type => 'Discussion'
    end
    
    class PageElement < ActiveRecord::Base
      belongs_to :page
      belongs_to :element, :polymorphic => true
      acts_as_list :scope => :page
    end
    
    class TodoList < ActiveRecord::Base
      has_one :page_element, :as => :element
      has_one :page, :through => :page_elements 
    end
    
    class Note < ActiveRecord::Base
      has_one :page_element, :as => :element
      has_one :page, :through => :page_elements 
    end
    
    class File < ActiveRecord::Base
      has_one :page_element, :as => :element
      has_one :page, :through => :page_elements 
    end
    
    class Discussion < ActiveRecord::Base
      has_one :page_element, :as => :element
      has_one :page, :through => :page_elements 
    end