[英]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.