16

Could somebody give me the working example of nested form using mongoid?

My models:

class Employee 
  include Mongoid::Document 
  field :first_name 
  field :last_name 
  embeds_one :address 
end

class Address 
  include Mongoid::Document 
  field :street 
  field :city 
  field :state 
  field :post_code 
  embedded_in :employee, :inverse_of => :address 
end
shingara
  • 46,608
  • 11
  • 99
  • 105
Kir
  • 7,981
  • 12
  • 52
  • 69

1 Answers1

25

Your models:

class Employee 
  include Mongoid::Document 

  field :first_name 
  field :last_name 
  embeds_one :address
  # validate embedded document with parent document
  validates_associated :address
  # allows you to give f.e. Employee.new a nested hash with attributes for
  # the embedded address object
  # Employee.new({ :first_name => "First Name", :address => { :street => "Street" } })
  accepts_nested_attributes_for :address
end

class Address 
  include Mongoid::Document 

  field :street 
  field :city 
  field :state 
  field :post_code 
  embedded_in :employee, :inverse_of => :address 
end

Your controller:

class EmployeesController < ApplicationController

  def new
    @employee = Employee.new
    # pre-build address for nested form builder
    @employee.build_address
  end

  def create
    # this will also build the embedded address object 
    # with the nested address parameters
    @employee = Employee.new params[:employee]

    if @employee.save
      # [..]
    end
  end      

end

Your template:

# new.html.erb
<%= form_for @employee do |f| %>
  <!-- [..] -->
  <%= f.fields_for :address  do |builder| %>
     <table>
       <tr>
         <td><%= builder.label :street %></td>
         <td><%= builder.text_field :street %></td>
       </tr>
       <!-- [..] -->
     </table>
  <% end %>
<% end %>

That should work for you!

Julian

Julian Maicher
  • 1,793
  • 14
  • 13
  • 2
    With mongoid >= 2.0.0.rc1 you don't need to explicitly say that your models should validate the embedded models as well. That is the default behaviour. See http://mongoid.org/docs/upgrading – Julian Maicher Feb 28 '11 at 08:40
  • Hi Julian Maicher, is this still the recommended way to approach with Mongoid 4? – Som Poddar Jul 31 '14 at 19:31
  • I strongly suggest you use the nested_form gem for nesting. Also, this answer is incomplete if you use strong parameters. @Julian It is not really related to the mongoid gem. Or actually, the only difference between `embedded` and `has_many` associations that I know of, is that you don't need `accepts_nested_attributes_for` with embedded stuff – Cyril Duchon-Doris Dec 20 '14 at 18:02
  • 2
    @JulianMaicher - Great example. It helped me a lot. Keep in mind in Rails 4 it is best to use a permit vs. using params directly. To allow nested params do this: `params.require(:employee).permit(:name, :addresses_attributes => [:address_type, :address, :id],)` @CyrilDD - From my testing both `embeds_many` and `accepts_nested_attributes_for` is required. – max kaplan Jun 09 '15 at 22:22
  • the pre-build advice is gold! – Maxim Zubarev Apr 06 '17 at 23:29