Been stuck on this for a while, I am using wizard gem and looking to save tenants attributes in a nested form. The attributes are being saved but are outputting nil in the database. Cant seem to understand why not sure if its the gem or, I am missing something obvious in the model or controller.
Parameters
Parameters: {"utf8"=>"✓", "authenticity_token"=>"xPqiDsUpnuLHCSnU+XuAUce4b/cTnM/gv6T7wxdIz4g=", "property"=>{"tenants_attributes"=>{"0"=>{"title"=>"Mr", "firstname"=>"Foo", "surname"=>"bar", "dateofbirth(1i)"=>"2013", "dateofbirth(2i)"=>"7", "dateofbirth(3i)"=>"21", "telno"=>"01143268375", "contact_type"=>"foo", "email"=>"example@gmail.com"}}}, "commit"=>"Create Tenant", "property_id"=>"58"}
here is the log showing tenant attributes as nil.
INSERT INTO "tenants" ("contact_type", "created_at", "dateofbirth", "email", "firstname", "property_id", "surname", "telno", "title", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [["contact_type", nil], ["created_at", Sun, 21 Jul 2013 10:53:00 UTC +00:00], ["dateofbirth", nil], ["email", nil], ["firstname", nil], ["property_id", nil], ["surname", nil], ["telno", nil], ["title", nil], ["updated_at", Sun, 21 Jul 2013 10:53:00 UTC +00:00]]
properties/build Controller
class Properties::BuildController < ApplicationController
include Wicked::Wizard
steps :tenant
def show
@property = Property.find(params[:property_id])
@tenant = @property.tenants.new
render_wizard
end
def update
@property = Property.find(params[:property_id])
@tenants = Tenant.find(params[:tenant])
case step
when :tenant
if @tenants.update_attributes(params[:tenants])
render_wizard @tenant
else
render :action => 'edit'
end
end
end
def create
@tenant = Tenant.create
if @tenant.save
flash[:success] = "Tenant Added"
redirect_to wizard_path(steps.first, :tenant_id => @tenant.id)
else
render 'edit'
end
end
end
property model
class Property < ActiveRecord::Base
attr_accessible :name, :address_attributes, :tenants_attributes
belongs_to :user
has_one :address, :as => :addressable
accepts_nested_attributes_for :address
validates_associated :address
has_many :tenants
accepts_nested_attributes_for :tenants
validates :name, presence: true, length: { maximum: 200 }
validates :address, presence: true
validates :user_id, presence: true
end
Tenant form
<h2> Tenant Form</h2>
<%= simple_form_for @property, :url => url_for(:action => 'create', :controller => 'properties/build'), :method => 'post' do |f| %>
<%= f.simple_fields_for :tenants do |f| %>
<%= f.input :title %>
<%= f.input :firstname %>
<%= f.input :surname %>
<%= f.input :dateofbirth %>
<%= f.input :telno %>
<%= f.input :contact_type %>
<%= f.input :email %>
<%= f.submit %>
<% end %>
You have several errors in your view. First, you are missing an end statement. Second, you are using f for the outer and inner form, so you are overriding outer with the inner. Try something like this:
<%= simple_form_for @property, :url => url_for(:action => 'create', :controller => 'properties/build'), :method => 'post' do |f| %>
# Fields for property (f.input...)
<%= f.simple_fields_for :tenants do |tenant| %>
# Fields For tenant (tenant.input...)
<% end %>
<% end %>
Also, I think you have an error here
@tenant = Tenant.create
if @tenant.save
flash[:success] = "Tenant Added"
redirect_to wizard_path(steps.first, :tenant_id => @tenant.id)
else
render 'edit'
end
When using if something.save
, you must use something.new
before it instead of something.create
(create
creates new record and saves it to the database, to there is no need to save it again, and new
just creates the record, but you must save it manually).
You probably need something like
@property = Property.new(params[:property])
if @property.save
flash[:success] = "Tenant Added"
redirect_to wizard_path(steps.first, :tenant_id => @tenant.id)
else
render 'edit'
end