Reputation: 8392
I try to create a nested model form for the has_one association. (i'm using Rails 4)
In my user, and adress model i have the following :
class User < ActiveRecord::Base
has_one :address
accepts_nested_attributes_for :address
end
class Address < ActiveRecord::Base
belongs_to :user
end
my user controller :
class UsersController < ApplicationController
.
.
.
def edit
@user = User.find(params[:id])
@user.build_address if @user.address.nil?
end
def update
@user = User.find(params[:id])
if @user.update(params.require(:user).permit(:user_name, address_attributes: [:street]))
flash[:success] = "Profile updated successfully"
sign_in @user
redirect_to @user
else
flash.now[:error] = "Cannot updating your profile"
render 'edit'
end
end
end
finally in my view i have :
= form_for(@user) do |f|
= render 'shared/error_messages', object: f.object
%div
= f.label :user_name, "User name"
= f.text_field :user_name
= f.fields_for :address do |add|
= addd.label :street
= d.text_field :street
= f.submit "Update"
When i try to fill street filed for the first time it works, but when i try to update i get the error : Failed to remove the existing associated address. The record failed to save after its foreign key was set to nil
any idea where is the error ? thank's
Upvotes: 26
Views: 12729
Reputation: 1349
There is an option to make it do a partial update if the record already exists:
accepts_nested_attributes_for(:address, update_only: true)
In your controller, include the nested id to the permitted params:
permit(:user_name, address_attributes: [:id, :street])
Documented here: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for
Upvotes: 38
Reputation: 1318
in your controller UsersController
, in the update
method, add the address: :id
to the address permitted attributes. Like this:
params.require(:user).permit(:user_name, address_attributes: [:id, :street]))
Upvotes: 23
Reputation: 35349
This error usually indicates that there is an existing record for the has_one
relationship. In other words, this particular user
object already has an address
record associated with it. This could happen while testing the form in the browser.
In this case, it seems like Rails is trying to create a new address record, and it has to do with how your edit
action is written.
Try this:
def edit
@user = User.find(params[:id])
@address = user.address || @user.build_address
end
Upvotes: 0