繁体   English   中英

在Rails 5.1中,如何使用一种形式来更新两个表?

[英]In Rails 5.1, how do I use one form to update two tables?

我一直在尝试获取一种形式来更新Ruby on Rails中的两个表。 我在这里进行了相当详尽的搜索,发现这些指南有些令人困惑。 我找到的最接近的答案是这样的:

Ruby on Rails从一种形式保存在两个表中

我大部分都复制了此答案,但仍然无法正常工作。 以下是相关的代码位:

模型-我有两个模型,供应商和帐户。 每个供应商应有一个帐户。

class Supplier < ApplicationRecord
  has_one :account
  accepts_nested_attributes_for :account
end

class Account < ApplicationRecord
  belongs_to :supplier
end

表格-不确定这是否完全正确

<h2>Please enter a supplier</h2>
  <%= form_for(@supplier) do |form| %>

<p>
  <%= form.label :name %><br>
  <%= form.text_field :name %>
</p>

<p>
 <%= form.fields_for :account do |f| %>
 <%= f.label :account_number %><br>
 <%= f.text_field :account_number %>
</p>

<p>
 <%= form.submit %>
</p>
 <% end %>
<% end %>

最后是SuppliersController

class SuppliersController < ApplicationController

  def index
    @suppliers = Supplier.all
  end

  def new
    @supplier = Supplier.new
    @supplier = build_account
  end

  def create
    @supplier = suppliers.build(supplier_params)

    if @supplier.save
      redirect_to suppliers_path
    else
      redirect_to root_path
    end
  end

  private

  def supplier_params
    params.require(:supplier).permit(:name, account_attributes: 
                                             [:account_number])
  end

end

我在SuppliersController的新操作的第二行上收到未定义的方法错误,我不知道为什么。

SupplierController调试打印输出以创建操作:

在2017年11月3日08:25:25 -0600开始为127.0.0.1的POST“ /供应商”供应商Controller#create作为HTML参数进行处理:{“ utf8” =>“✓”,“ authenticity_token” =>“ KEqvPgjrYmuBux3qWCQJLAkSLQ4z1ns4HsK2P9sWl JoWT3vlL / kP42XpU8adllOaqSA16izYJ0SA ==“,”供应商“ => {”名称“ =>”“,” account_attributes“ => {” account_number“ =>”“}},” commit“ =>”创建供应商“}

(0.1ms)开始交易

SQL(0.5ms)插入“供应商”(“ created_at”,“ updated_at”,“名称”)值(?,?,?)[[“ created_at”,“ 2017-11-03 14:25:25.388933”] ,[“ updated_at”,“ 2017-11-03 14:25:25.388933”],[“名称”,“鲍勃”]]

(0.6ms)提交事务(0.0ms)开始事务

供应商负载(1.0毫秒)选择“供应商”。*从“供应商”中选择“供应商”。“ id” =? LIMIT? [[“ id”,6],[“ LIMIT”,1]] SQL(0.3ms)插入“帐户”(“ created_at”,“ updated_at”,“帐户编号”,“供应商id”)值(?,?, ?,?)[[“ created_at”,“ 2017-11-03 14:25:25.424367”],[“ updated_at”,“ 2017-11-03 14:25:25.424367”],[“ account_number”,“ 456456456 “],[” supplier_id“,6]]

(0.6ms)提交事务

供应商:#Supplier id:6,created_at:“ 2017-11-03 14:25:25”,updated_at:“ 2017-11-03 14:25:25”,名称:“ Bob”

帐户:#帐户ID:1,created_at:“ 2017-11-03 14:25:25”,updated_at:“ 2017-11-03 14:25:25”,account_number:“ 456456456”,Supplier_id:6

(0.0ms)开始事务(0.0ms)提交事务

重定向到http:// localhost:3000 / suppliers已完成302在51ms内找到(ActiveRecord:4.6ms)

您的问题是build_account是供应商对象上的方法。 有了代码后,它当前正在尝试运行build_account,就像它是SuppliersController上的方法一样

因此,您应该尝试将控制器方法更新为new:

def new
  @supplier = Supplier.new
  @account = @supplier.build_account
end

这将针对您刚刚实例化的供应商对象调用build_account ,并将结果作为实例化的帐户对象返回,并与其所属的供应商实例相关联。

build_account方法是通过您在供应商模型中定义的关联(您说has_one :account http://guides.rubyonrails.org/association_basics.html#has-one-association-reference此处的文档介绍了以这种方式创建的所有方法。

编辑

在跟上有关创建动作的问题之后,应该更新控制器。 在注释中,我们已经调试了模型,它们似乎可以按我们希望的那样工作,因此一旦更新,控制器应以下列方式工作:

def create
  # Created a Supplier, but not yet persisted.
  @supplier = Supplier.new(supplier_params)

  # Persists the supplier, giving him an id, which can then be used
  # through implicit autosave functionality to take the nested params
  # to build the associated account. All of these operations are wrapped
  # in a single DB transaction, ensuring nothing is left dangling if
  # there is a validation failure
  if @supplier.save
    redirect_to suppliers_path
  else
    redirect_to root_path
  end
end

基于关联自动保存功能,应在保存供应商时基于从表单传递的嵌套参数自动创建新的关联记录(帐户),而不必添加任何其他代码来显式处理此问题。 更多自动保存选项记录在这里: http : //api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html

从本节的指南

4.1.1归属者添加的方法

Book模型的每个实例将具有以下方法:

因此,正如我的朋友在下面指出的那样

@supplier = Supplier.build_account // wrong
@account = @supplier.build_account 

会是正确的

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM