24

我尝试为 has_one 关联创建一个嵌套模型表单。(我正在使用 Rails 4)

在我的用户和地址模型中,我有以下内容:

class User < ActiveRecord::Base
 has_one :address
 accepts_nested_attributes_for :address
end

class Address < ActiveRecord::Base
 belongs_to :user

end

我的用户控制器:

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

最后在我看来,我有:

= 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"

当我第一次尝试填写街道文件时它可以工作,但是当我尝试更新时出现错误:Failed to remove the existing associated address. The record failed to save after its foreign key was set to nil

知道错误在哪里吗?谢谢

4

3 回答 3

36

如果记录已存在,则可以选择使其进行部分更新:

accepts_nested_attributes_for(:address, update_only: true)

记录在这里:http ://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for

于 2013-12-22T08:52:13.233 回答
23

在您的控制器UsersController中,在update方法中,添加address: :id地址允许的属性。像这样:

params.require(:user).permit(:user_name, address_attributes: [:id, :street]))
于 2013-09-24T15:34:55.800 回答
0

此错误通常表明存在has_one关系的现有记录。换句话说,这个特定user的对象已经有一个address与之关联的记录。在浏览器中测试表单时可能会发生这种情况。

在这种情况下,Rails 似乎正在尝试创建新的地址记录,这与您的edit操作的编写方式有关。

尝试这个:

def edit
  @user = User.find(params[:id]) 
  @address = user.address || @user.build_address
end 
于 2013-09-24T14:17:50.260 回答