【问题标题】:Can't update my nested model form for has_one association无法更新我的 has_one 关联的嵌套模型表单
【发布时间】:2013-09-24 14:16:02
【问题描述】:

我尝试为 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

知道错误在哪里吗?谢谢

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    如果记录已经存在,可以选择让它进行部分更新:

    accepts_nested_attributes_for(:address, update_only: true)
    

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

    【讨论】:

    • 很好,我稍后会尝试,在它需要添加嵌套属性的 id 之前,现在文档更清楚这一点谢谢@micaeked
    • 伙计,我尝试了所有与设计和嵌套表单相关的答案,你是唯一一个有明确、简单答案和最好答案的人,它成功了!!!非常感谢,我努力(14 小时)直到做到这一点!
    【解决方案2】:

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

    params.require(:user).permit(:user_name, address_attributes: [:id, :street]))
    

    【讨论】:

    • 哇,它有效,谢谢,这是我搜索的内容:D,但你能解释一下我的错误的原因吗
    • 你能解释一下为什么我应该将 id 添加到我的 address_attributes 中吗
    • @medBo 我不知道为什么必须将 :id 包含到必须更新的嵌套属性中。它没有特别记录,几个月前我遇到了完全相同的问题,在找到解决方案之前挣扎了一个周末。也许更高级/专家 Rails 开发人员可以提供帮助。很高兴能提供帮助;-)
    • merci beaucoup :D 我知道你是法国人 ;) 谢谢你的帮助
    • 不安全。最好使用update_only: true 选项,正如stoodfarback 解释的那样。
    【解决方案3】:

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

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

    试试这个:

    def edit
      @user = User.find(params[:id]) 
      @address = user.address || @user.build_address
    end 
    

    【讨论】:

    • 但我尝试更新信息而不是创建新记录!!
    • 为什么要添加 [at]address 实例变量?在我的代码中,我不需要任何变量 [at]address !!
    • 有办法说如果user.address已经存在那么@user.build_address(existing_adress) ???
    • 这是assign address to either user.address, or, if that's nil, assign to a new address instance (@user.build_address)
    • 解决方案是将 :id 添加到强参数中,如@d34n5 所说
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多