Search code examples
mongodbsinatramongoidmodel-associations

Value of atomizing class field?


Consider the following Mongoid Model

class Doc
  include Mongoid::Document
  field :name, type: String
  embeds_many :images
  embeds_many :videos
end

class Image
  include Mongoid::Document
  field :url, type: String
  field :caption, type: String
  embedded_in :Doc
end

class Video
  include Mongoid::Document
  field :url, type: String
  field :caption, type: String
  embedded_in :Doc
end

versus this model

class Doc
  include Mongoid::Document
  field :name, type: String
  embeds_many :images
  embeds_many :videos
end

class Image
  include Mongoid::Document
  embeds_many :urls
  embeds_many :captions
  embedded_in :Doc
end

class Video
  include Mongoid::Document
  embeds_many :urls
  embeds_many :captions
  embedded_in :Doc
end

class Url
  include Mongoid::Document
  embedded_in :image
  embedded_in :video
  field :url, type: String
end

class Caption
  include Mongoid::Document
  embedded_in :image
  embedded_in :video
  field :caption, type: String
end

What the benefit of each model over the other?

Should I go for the first one for it's brevity, or should I atomize it to the url.url point so that I have more control for queries later?


Solution

  • The first model allows you to associate exactly one URL with each image or video. The second model allows you to associate many URLs with each image or video.

    Which is a better fit for your business requirements? Is it possible for an image to have many URLs or is there only one?

    Personally, I'd go with the first model unless you strictly need many URLs for a given image. Since the URL of each piece of media on the web is pretty much guaranteed to be unique, there's really no point in over-normalizing the data structure. You'll have just as many records in the URL class as the combined total of Video and Image records, so what would you save?

    If it was some other string field that could have non-unique values (say Tags, for example) then it makes great sense to break it out since you'll have dramatically fewer records in the Tags model then the Image and Video records, assuming a high degree or tag re-use.

    Make sense?