I’m using rails 3.2 and I building a nested form. But things are not working as I expect. First of all, my model is a Company with has many Addresses. Here is the model
class Company
include Mongoid::Document
include Mongoid::Timestamps
field :name, :type => String
field :description, :type => String
field :order_minimun, :type => Float
belongs_to :user
has_many :addresses
validates_presence_of :name, :description, :order_minimun
validates_length_of :name, minimum:2, maximum: 30
validates_length_of :description, minimum:5, maximum: 140
validates :order_minimun, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0 }
accepts_nested_attributes_for :addresses
validates_associated :addresses
end
class Address
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Spacial::Document
field :street, :type => String
field :number, :type => Integer
field :phone, :type => String
field :location, :type => Array, spacial: {lat: :latitude, lng: :longitude, return_array: true }
embeds_many :delivery_zones
belongs_to :company
belongs_to :city
has_many :openingTimeRange
validates_presence_of :street, :number
validates_length_of :street, minimum:1, maximum: 30
validates_length_of :number, minimum:1, maximum: 6
validates_length_of :phone, minimum:5, maximum: 60
attr_accessible :street, :number, :company_id, :city_id, :location, :phone, :delivery_zones, :latitude, :longitude
end
As you can see the Company model has:
accepts_nested_attributes_for :addresses
validates_associated :addresses
So, I think a can build a nested form. Here is the code of the form
<%= form_for [:admin,@company],:url =>admin_company_path(@company), :html => {:class => "form-horizontal"} do |f|%>
<legend><%= t '.legend' %></legend>
<%= group_input_field f, :name%>
<%= group_field_for f, :description do%>
<%= f.text_area :description, :rows => 5%>
<% end -%>
<%= group_input_field f, :order_minimun%>
<%= f.fields_for :addresses do |builder|%>
<%= render 'address_fields', :f=> builder%>
<% end %>
<div class="form-actions">
<%= f.submit :class => 'btn btn-primary btn-large', :disable_with => t('button.saving') %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
admin_companies_path, :class => 'btn btn-large btn-danger' %>
</div>
<% end %>
the _address_fields.html.erb
<%= group_input_field f, :street%>
<%= group_input_field f, :number%>
I have a simple helper to generate the form fields with bootstrap
def group_input_field(f,field, options={})
has_error = f.object.errors.has_key? field
klass = has_error ? "control-group error": "control-group"
content_tag(:div, :class => klass) do
f.label(field, :class => 'control-label')+
content_tag(:div, :class => 'controls') do
f.text_field(field, :class => 'input')+
show_error(f.object,field,has_error)+
show_help(options)
end
end
end
Finaly the controller:
class Admin::CompaniesController < ApplicationController
def new
#crea una nueva compañia
@company = Company.new
end
def edit
@company = Company.find params[:id]
end
def create
@company = Company.new(params[:company])
if @company.save
redirect_to :action => 'index'
else
render 'new'
end
end
def update
@company = Company.find(params[:id])
if @company.update_attributes(params[:company])
redirect_to :action => 'index'
else
render 'edit'
end
end
end
What is happening a couple of things. First, I have a company with two addresses, and I am able to edit the first one, any change on the second one is not persisted. Then the addresses fields are not validated (if i leave everything in blank when i open the form again the addresses were not save and I can see the original values). And when edit a field in any address, and any field value of the company is not valid, after the form is submited i can see the errors on the company model, but the address are displayed with the original values, so the edited values were lost.
Hope be clear.
Thanks in advance.
Well, I’ve found the answer. I was using the version of mongoid 3.0.4. I run the command bundle update mongoid and mongoid was updated to the version 3.0.6. And the problems were fixed.
Thanks. Hope it helps