具有嵌套 fields_for 的表单,可保存到多条记录
Form with nested fields_for which saves to multiple records
我有三个模型,companies
、transactions
和 subtransactions
。每个 has_many 的下一个。我需要构建一个可以同时保存 transactions
和 subtransactions
的多个记录的表单。
我正在为表单的最佳方法和保存到数据库的适当方法而苦苦挣扎。理想情况下,如果所有记录都通过验证,记录将立即保存。
我的简体:
<%= form_for(@transaction) do |f| %>
<div class="field" id="transaction_amount">
<%= f.label :total %><br>
<%= f.text_field :total %>
</div>
<% 1.upto(5) do |i| %>
<%= fields_for("subtransaction[#{i}]") do |s| %>
<div class="field" id="subtotal_amount">
<%= s.label :subtotal, "Subtotal #{i}" %><br>
<%= s.text_field :subtotal %>
</div>
<% end %>
<% end %>
<% end %>
我的交易控制器:
def new
@transaction = company.transactions.build if logged_in?
end
def create
@transaction = company.transactions.build(transaction_params)
params[:subtransaction].each do |i|
# build and save
end
if @transaction.save ## @subtransaction.save
flash[:success] = "Success!"
redirect_to success_url
else
render :new
end
end
型号
class Transaction < ActiveRecord::Base
has_many :subtransations
accepts_nested_attributes_for :subtransactions
end
控制器
def new
@transaction = Transaction.new
@transaction.subtransactions.build
end
def create
company = Company.first # Or whatever you need.
# We merge the company id to the transaction params since
# a transaction belongs_to a company.
@transaction = Transaction.create!(create_params.merge(company_id: company.id))
end
private
def create_params
params.require(:transaction).permit(
:total,
subtransactions_attributes: [:id, :subtotal]
)
end
查看
<%= form_for(@transaction) do |f| %>
<div class="field">
<%= f.label :total %><br>
<%= f.text_field :total %>
</div>
<%= f.fields_for :subtransaction do |s| %>
<div class="field" id="subtotal_amount">
<%= s.label :subtotal %><br>
<%= s.text_field :subtotal %>
</div>
<% end %>
<% end %>
这将允许只用交易记录创建一个子交易
如果您想要创建多个 subtransaction
记录,您应该使用 cocoon gem,它易于设置并且会节省很多宝贵的时间。
这样做的方法是通过各种模型传递 nested
属性:
#app/models/company.rb
class Company < ActiveRecord::Base
has_many :transactions
accepts_nested_attributes_for :transactions
end
#app/models/transaction.rb
class Transaction < ActiveRecord::Base
has_many :sub_transactions
accepts_nested_attributes_for :sub_transactions
end
这将使您能够使用以下内容:
#app/controllers/transactions_controller.rb
class TransactionsController < ApplicationController
def new
@transaction = company.transactions.new
5.times do
@transaction.sub_transactions.build
end
end
def create
@transaction = company.transactions.new transaction_params
@transaction.save
end
private
def transaction_params
params.require(:transaction).permit(sub_transactions_attributes: [:subtotal])
end
end
然后...
#app/views/transactions/new.html.erb
<%= form_for @transaction do |f| %>
<%= f.fields_for :sub_transactions do |s| %>
<%= s.text_field :subtotal %>
<% end %>
<%= f.submit %>
<% end %>
这将允许您通过主对象保存各种嵌套属性。这是正确的 conventional 方法。
我有三个模型,companies
、transactions
和 subtransactions
。每个 has_many 的下一个。我需要构建一个可以同时保存 transactions
和 subtransactions
的多个记录的表单。
我正在为表单的最佳方法和保存到数据库的适当方法而苦苦挣扎。理想情况下,如果所有记录都通过验证,记录将立即保存。
我的简体:
<%= form_for(@transaction) do |f| %>
<div class="field" id="transaction_amount">
<%= f.label :total %><br>
<%= f.text_field :total %>
</div>
<% 1.upto(5) do |i| %>
<%= fields_for("subtransaction[#{i}]") do |s| %>
<div class="field" id="subtotal_amount">
<%= s.label :subtotal, "Subtotal #{i}" %><br>
<%= s.text_field :subtotal %>
</div>
<% end %>
<% end %>
<% end %>
我的交易控制器:
def new
@transaction = company.transactions.build if logged_in?
end
def create
@transaction = company.transactions.build(transaction_params)
params[:subtransaction].each do |i|
# build and save
end
if @transaction.save ## @subtransaction.save
flash[:success] = "Success!"
redirect_to success_url
else
render :new
end
end
型号
class Transaction < ActiveRecord::Base
has_many :subtransations
accepts_nested_attributes_for :subtransactions
end
控制器
def new
@transaction = Transaction.new
@transaction.subtransactions.build
end
def create
company = Company.first # Or whatever you need.
# We merge the company id to the transaction params since
# a transaction belongs_to a company.
@transaction = Transaction.create!(create_params.merge(company_id: company.id))
end
private
def create_params
params.require(:transaction).permit(
:total,
subtransactions_attributes: [:id, :subtotal]
)
end
查看
<%= form_for(@transaction) do |f| %>
<div class="field">
<%= f.label :total %><br>
<%= f.text_field :total %>
</div>
<%= f.fields_for :subtransaction do |s| %>
<div class="field" id="subtotal_amount">
<%= s.label :subtotal %><br>
<%= s.text_field :subtotal %>
</div>
<% end %>
<% end %>
这将允许只用交易记录创建一个子交易
如果您想要创建多个 subtransaction
记录,您应该使用 cocoon gem,它易于设置并且会节省很多宝贵的时间。
这样做的方法是通过各种模型传递 nested
属性:
#app/models/company.rb
class Company < ActiveRecord::Base
has_many :transactions
accepts_nested_attributes_for :transactions
end
#app/models/transaction.rb
class Transaction < ActiveRecord::Base
has_many :sub_transactions
accepts_nested_attributes_for :sub_transactions
end
这将使您能够使用以下内容:
#app/controllers/transactions_controller.rb
class TransactionsController < ApplicationController
def new
@transaction = company.transactions.new
5.times do
@transaction.sub_transactions.build
end
end
def create
@transaction = company.transactions.new transaction_params
@transaction.save
end
private
def transaction_params
params.require(:transaction).permit(sub_transactions_attributes: [:subtotal])
end
end
然后...
#app/views/transactions/new.html.erb
<%= form_for @transaction do |f| %>
<%= f.fields_for :sub_transactions do |s| %>
<%= s.text_field :subtotal %>
<% end %>
<%= f.submit %>
<% end %>
这将允许您通过主对象保存各种嵌套属性。这是正确的 conventional 方法。