[英]In Rails 5.1, how do I use one form to update two tables?
我一直在尝试获取一种形式来更新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
从本节的指南
Book模型的每个实例将具有以下方法:
因此,正如我的朋友在下面指出的那样
@supplier = Supplier.build_account // wrong
@account = @supplier.build_account
会是正确的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.