I may just be missing something simple, but I am relatively inexperienced so it is likely. I’ve searched extensively for a solution without success.
I am using the fields_for function to build a nested form using the accepts_nested_attributes_for function. If the submit on the form fails the params are passed to the render of the new template only for the parent model. How do I pass the nested params for the child model so that fields that have been filled out previously remain filled. Note that I am using simple_form and HAML but I assume this shouldn’t impact the solution greatly.
My models:
class Account < ActiveRecord::Base
attr_accessible :name
has_many :users, :dependent => :destroy
accepts_nested_attributes_for :users, :reject_if => proc { |a| a[:email].blank? }, :allow_destroy => true
end
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation
belongs_to :account
end
My accounts controller:
def new
@account = Account.new
@account.users.build
end
def create
@account = Account.new(params[:account])
if @account.save
flash[:success] = "Welcome."
redirect_to @account
else
@account.users.build
<- I suspect I need something here but unsure what
render :new
end
end
The key part of the accounts/new view:
= simple_form_for @account do |f|
= f.input :name
= f.simple_fields_for :users do |u|
= u.input :email
= u.input :password
= u.input :password_confirmation
= f.button :submit, :value => "Sign up"
My params on a failed save are:
:account {"name"=>"In", "users_attributes"=>{"0"=>{"email"=>"u@e.com", "password"=>"pass", "password_confirmation"=>"pass"}}}
As you can see, the key information, in the users_attributes section, is stored but I can’t seem to have the email address default into the new form. Account name on the other hand is filled automatically as per Rails standard. I’m not sure if the solution should live in the accounts controller or in the accounts/new view, and have not had any luck with either.
Answers with .erb are, of course, fine.
I’m fairly new to Ruby and Rails so any assistance would be much appreciated.
The problem lies with
attr_accessible, which designates the only attributes allowed for mass assignment.I feel a bit silly in that I actually stated the problem in a comment last night and failed to notice:
This is true, but with
attr_accessible :name, you’ve precluded every attribute but name being mass-assigned,users_attributes=included. So when you build a new account viaAccount.new(params[:account]), theusers_attributespassed along in params are thrown away.If you check the log you might note this warning:
You can solve your original problem by adding
:users_attributesto theattr_accessiblecall in the account class, allowing it to be mass-assigned.