Search code examples
ruby-on-railsruby-on-rails-4mongoidembedded-documents

Rails 4 MongoID embedded Documents


I have the following model

class Professional
  include Mongoid::Document
  field :first_name, type: String
  field :last_name, type: String
  field :company_name, type: String
  field :address, type: String


  validates :first_name, length: { minimum: 5, :message => "What" }, format: { with: /\A[a-zA-Z]+\z/, message: "only allows letters" }
end

I want to include a embedded documents where i can store multiple office address. Am looking for the following Structure of the DB

{
  "first_name": "Harsha",
  "last_name": "MV",
  "company_name": "Mink7",
  "offices": [
    {
      "name": "Head Office",
      "address": "some address here"
    },
    {
      "name": "Off Site Office",
      "address": "some large address here"
    }
  ]
}

Solution

  • You will have to define that the model is embedding an office object and vice versa, explanation here: http://mongoid.org/en/mongoid/docs/relations.html. I'm guessing that you need a 1-N relation, so that a Professional can embed several offices? In that case, something like this should work.

    Professional model

    class Professional
      include Mongoid::Document
      field :first_name, type: String
      field :last_name, type: String
      field :company_name, type: String
      field :address, type: String
    
    
      validates :first_name, length: { minimum: 5, :message => "What" }, format: { with: /\A[a-zA-Z]+\z/, message: "only allows letters" }
    
      embeds_many :offices, class_name: "Office"
    end
    

    Office model

    class Office
      include Mongoid::Document
      field :name, type: String
      field :address, type: String
    
      embedded_in :professional, :inverse_of => :offices
    end
    

    Remember that if you are going to use one form for these objects you'll have to do a nested form, something like (or just google something up):

    <%= form_for @professional, :url => { :action => "create" } do |o| %>
        <%= o.text_field :first_name %>
        <%= o.text_field :last_name %>
    
        <%= o.fields_for :office do |builder| %>
            <%= builder.text_field :name %>
            <%= builder.text_field :address %>
        <% end %>
    <% end %>
    

    Note that nothing is tested.