簡體   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