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
Related
I have a problem : when a customer enters his shipping and billing informations in my form, the fields of the address model lose all information if the page is reloaded.
It works with the other fields, like email, that are included directly in the order model. How could I leave the fields filled after reloading ?
Here's my new.html.erb file :
<%= form_for #order do |f| %>
<ul>
<% #order.errors.each_with_index do |msg, i| %>
<li><%= msg[1] %></li>
<% end %>
</ul>
<%= f.text_field :email, placeholder: "email" %>
<%= f.fields_for :shipping_address_attributes do |sa| %>
<%= sa.text_field :first_name, placeholder: "Firstname" %>
<%= sa.text_field :last_name, placeholder: "Name", autocomplete: true %>
<%= sa.text_field :address1, placeholder: "Address", autocomplete: true %>
#etc.
<% end %>
<p><%= f.submit 'Next step' %></p>
<% end %>
My models :
class Order < ActiveRecord::Base
belongs_to :billing_address, :class_name => "Address"
belongs_to :shipping_address, :class_name => "Address"
accepts_nested_attributes_for :shipping_address
accepts_nested_attributes_for :billing_address, reject_if: :bill_to_shipping_address
class Address < ActiveRecord::Base
belongs_to :user
has_many :billing_addresses, :class_name => "Order", :foreign_key => "billing_address_id", dependent: :nullify
has_many :shipping_addresses, :class_name => "Order", :foreign_key => "shipping_address_id", dependent: :nullify
validates_presence_of :first_name, :last_name, :address1, :city, :country, :phone, :postal
and my order_controller.rb:
def new
#user = current_user
#order_items = current_order.order_items
#order = current_order
#amount = #order.subtotal
end
def update
#order_items = current_order.order_items
#order = current_order
if #order.update(order_params)
redirect_to recapitulatif_de_la_commande_path
else
redirect_to(:back)
end
end
EDIT
Maybe the error is due to the fact that the order is not linked to any shipping address before the update action ? It works only if address model validate the presence of each attributes.
Any idea ?
I have models for Venues and Photos:
class Venue < ActiveRecord::Base
has_and_belongs_to_many :photos
validates :name, presence: true
validates :permalink, presence: true, uniqueness: true
def to_param
permalink
end
end
class Photo < ActiveRecord::Base
mount_uploader :image, PhotoUploader
has_and_belongs_to_many :venues
end
I'm using simple_form to make the following form:
<div class="content-box">
<%= simple_form_for [:admin, #venue] do |f| %>
<%= f.input :name %>
<%= f.input :permalink %>
<%= f.input :description, input_html: { cols: 100, rows: 6 }%>
<%= f.input :address %>
<%= f.input :city %>
<%= f.input :phone %>
<%= f.association :photos %>
<%= f.button :submit, class: 'small radius' %>
<% end %>
</div>
And here is my controller for the Edit and Update methods:
class Admin::VenuesController < ApplicationController
def edit
#venue = Venue.find_by_permalink!(params[:id])
#photos = #venue.photos.all
end
def update
#venue = Venue.find_by_permalink!(params[:id])
if #venue.update_attributes(venue_params)
redirect_to edit_admin_venue_path(#venue), notice: 'Venue was successfully updated.'
else
render action: "edit"
end
end
private
def venue_params
params.require(:venue).permit(:name, :permalink, :description, :address, :city, :phone, :photo_ids)
end
end
The problem is that when I update using the form, all of the attributes for the venue model update fine, but the photo_ids are not updated or stored. I'm guessing it's something simple, but I'm not sure what it is. I'm using Rails 4, btw.
You need to permit photo_ids as an Array because photo_ids is passed as an Array upon form submission. Currently, photo_ids are not getting updated as you didn't permit them as an Array.
Update the venue_params as below:
def venue_params
params.require(:venue).permit(:name, :permalink, :description, :address, :city, :phone, :photo_ids => [])
end
Notice: :photo_ids => [] and NOT :photo_ids
Im struggling with a nested form in Rails 4, this is the first time that I made a form of that kind. I have read lots of documentation but Im not able to make it work. :-(
I have two models: Person and Disease. One person can have many diseases and one disease belongs to person. Looks quite simple. The form for Diseases is not saved in the database.
Person Model:
class Person < ActiveRecord::Base
belongs_to :user
has_many :diseases, :dependent => :destroy #if you delete a person you also delete all diseases related
has_many :appointments, :dependent => :destroy
validates_presence_of :name, :email
validates :name, :length => {:maximum => 50, :too_long => "name is too long"}
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, format: { :with => VALID_EMAIL_REGEX , message: "is invalid" }
accepts_nested_attributes_for :diseases
end
Disease Model:
class Disease < ActiveRecord::Base
belongs_to :person
has_many :treatments
validates_presence_of :name, :start
validates :name, :length => {:maximum => 50, :too_long => "is too long, you can use the description field"}
validate :start_must_be_before_end, :unless => [:chronical, :unfinished], :presence => true
validates :end, :presence => true, :unless => [:chronical, :unfinished], :presence => true
validates :description, :length => {:maximum => 5000, :too_long => "is too long"}
def start_must_be_before_end
if self[:end] < self[:start]
errors.add(:start, "must be before end time")
return false
else
return true
end
end
end
People Controller:
def create
current_user
#person = Person.new(person_params)
#person.user_id = #current_user.id
respond_to do |format|
if #person.save
format.html { redirect_to #person, notice: 'Person was successfully created.' }
format.json { render action: 'show', status: :created, location: #person }
else
format.html { render action: 'new' }
format.json { render json: #person.errors, status: :unprocessable_entity }
end
end
end
def person_params
params.require(:person).permit(:name, :surname, :gender, :birthdate, :bloodtype, :user_id, :phone, :email, diseases_attributes: [:id, :description] )
end
Form:
<%= simple_form_for #person do |f| %>
<%= f.input :name %>
<%= f.input :email %>
<%= simple_fields_for :diseases do |my_disease| %>
<%= my_disease.input :description %>
<% end %>
<%= f.button :submit %>
<% end %>
Thanks a lot for your help.
The issue is with line <%= simple_fields_for :diseases do |my_disease| %>.It should be
<%= f.simple_fields_for :diseases do |my_disease| %>
This should work.
<%= simple_form_for #person do |f| %>
<%= f.input :name %>
<%= f.input :email %>
<%= f.simple_fields_for :diseases do |my_disease| %> #here
<%= my_disease.input :description %>
<% end %>
<%= f.button :submit %>
<% end %>
For more Info,see this API
I'm trying to update my associated model, but it's not updating to the database and i'm not sure what to try next.
Model
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation,
:remember_me, :username, :login, :first_name,
:last_name, :home_phone, :cell_phone,
:work_phone, :birthday, :home_address,
:work_address, :position, :company, :user_details
has_one :user_details, :dependent => :destroy
accepts_nested_attributes_for :user_details
end
class UserDetails < ActiveRecord::Base
belongs_to :user
attr_accessible :home_phone, :position
end
Controller
# PUT /contacts/1/edit
# actually updates the users data
def update_user
#userProfile = User.find(params[:id])
respond_to do |format|
if #userProfile.update_attributes(params[:user])
format.html {
flash[:success] = "Information updated successfully"
render :edit
}
else
format.html {
flash[:error] = resource.errors.full_messages
render :edit
}
end
end
end
View
<%= form_for(#userProfile, :url => {:controller => "my_devise/contacts", :action => "update_user"}, :html => {:class => "form grid_6"}, :method => :put ) do |f| %>
<%= f.label :username, "Username" %>
<%= f.text_field :username, :required => "required" %>
<%= f.fields_for :user_details do |d| %>
<%= d.label :home_phone, "Home Phone" %>
<%= d.text_field :home_phone %>
<% end %>
<% end %>
<% end %>
Your attr_accessible should accept user_details_attributes, not just user_details.
I am new to rails and using a combination of formtastic, activeadmin,sti and polymorphic associations to build a form
When I I can create a nested form with the address parent with no problem, but when i introduce STI and attempt to build_origin_address instead of build_address, that is when I get the error below when loading the edit view
NameError in Admin/leads#edit
Showing .../app/views/admin/leads/_form.erb where line #3 raised:
uninitialized constant Lead::OriginAddress
Models:
class Address < ActiveRecord::Base
belongs_to :addressable, :polymorphic => true
belongs_to :lead
validates :line1, :presence => true, :length => {:minimum => 2}
attr_accessible :line1, :line2, :city, :state, :zip, :country
end
class OriginAddress < Address
end
class DestinationAddress < Address
end
class Lead < ActiveRecord::Base
has_one :origin_address, :dependent => :destroy, :as => :addressable
accepts_nested_attributes_for :origin_address, :allow_destroy => true
end
partial used in edit view:
<%= semantic_form_for [:admin, #lead] do |f| %>
<% #lead.build_origin_address unless #lead.origin_address %>
<%= f.inputs :name => "Lead Info" do %>
<%= f.input :first_name %>
<%= f.input :last_name %>
<% end %>
<%= f.semantic_fields_for :origin_address do |origin| %>
<%= origin.inputs :name => "Origin Address" do %>
<%= origin.input :line1 %>
....
<% end %>
<% end %>
<%= f.buttons do %>
<%= f.commit_button %>
<% end %>
<% end %>
I think you must define #lead before your form.