Ruby on rails 使用Rails 5在一个表单中创建记录和从属记录
我很难理解这个问题。我有一个属于另一个模型客户的模型发票,一个客户有很多发票 因此,没有客户就无法创建发票。我希望能够创建一个客户与发票在同一时间与相同的形式 现在我有了它,这样你就可以手动输入一个发票id,一切都很好,但这对于实际使用该应用程序的人来说并不理想,原因很明显 我已经阅读了这篇文章,但我仍然不理解,也不确定这是否仍然适用于Rails 5: 上述答案仍然是正确的方法吗?有人能澄清一下,也许能给我一些代码试试吗?谢谢Ruby on rails 使用Rails 5在一个表单中创建记录和从属记录,ruby-on-rails,Ruby On Rails,我很难理解这个问题。我有一个属于另一个模型客户的模型发票,一个客户有很多发票 因此,没有客户就无法创建发票。我希望能够创建一个客户与发票在同一时间与相同的形式 现在我有了它,这样你就可以手动输入一个发票id,一切都很好,但这对于实际使用该应用程序的人来说并不理想,原因很明显 我已经阅读了这篇文章,但我仍然不理解,也不确定这是否仍然适用于Rails 5: 上述答案仍然是正确的方法吗?有人能澄清一下,也许能给我一些代码试试吗?谢谢 <%= form_for(invoice) do |f| %
<%= form_for(invoice) do |f| %>
<% if invoice.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(invoice.errors.count, "error") %>
prohibited this invoice from being saved:</h2>
<ul>
<% invoice.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<h2>Customer Info</h2>
<hr>
<div class="field">
<%= f.label :customer_id %>
<%= f.number_field :customer_id %>
</div>
<!-- My customer model has more fields that I want to go here (name, address, and phone_number) -->
[...] other regular invoice fields here...
<div class="actions">
<%= f.submit %>
</div>
<% end %>
您可能想使用:创建动态嵌套表单这是您尝试在其中执行的嵌套表单: ,9.2嵌套形式 ,
有很多不同的库可以在这种情况下提供帮助。但我将尝试提出一种仅适用于Rails的解决方案 因此,为了分析你的情况,我猜我们需要解决两种情况。第一个用于为现有客户添加发票,第二个用于在创建发票的同时创建新客户。在我看来,最直接的方法是在表单中添加两个单独的字段。第一个字段是选择下拉列表,您可以从现有客户中进行选择,第二个字段是文本字段,如果选择字段中没有匹配项,您可以在其中输入客户的名称 逻辑是首先检查下拉列表中是否选择了任何内容,在这种情况下,textfield中的任何文本都将被忽略。但是如果没有从下拉列表中选择任何内容,那么它将基于文本字段创建Customer 以下是我如何实现这一目标的建议:
class Invoice < ActiveRecord::Base
belongs_to :customer
validate :customer_id, presence: true
# A dynamic attribute that is NOT represented by a database column in the Invoice model, but only used for the form
attr_accessor :customer_name, :customer_address #, plus your other fields
before_validation on: :create do
if customer_id.nil? && customer_name.present?
# Use create! (with !) so that an error is raised if the customer
# could not be created which will abort the entire save transaction
self.customer = Customer.create!(name: customer_name, address: customer_address)
# Add your other customer attributes above as well
end
end
end
然后以你的形式
<%= form_for(invoice) do |f| %>
<h2>Customer Info</h2>
<hr>
<div class="field">
<%= f.label :customer_id, "Choose existing Customer" %>
<%= f.select :customer_id, options_from_collection_for_select(Customer.all, :id, :name, invoice.customer_id) %>
</div>
<div class="field">
<%= f.label :customer_name, "... or create a new Customer" %>
<%= f.text_field :customer_name %>
</div>
<div class="field">
<%= f.label :customer_address, "New customer address" %>
<%= f.text_field :customer_address %>
</div>
<!-- Repeat for all your other Customer attributes -->
[...] other regular invoice fields here...
<div class="actions">
<%= f.submit %>
</div>
<% end %>
并且不要忘记允许控制器Invoice.createparams.permit中的附加参数属性:customer\u name,:customer\u address
当然,在这方面有一些事情可以提高效率,但我希望这可以展示Rails提供的一些开箱即用的特性,以解决类似的情况,我认为如果您对Rails有些陌生,最好关注这一点。在这种情况下可以使用嵌套属性。 在customer.rb文件中,添加以下内容:发票 在白名单参数中,添加发票\属性:[发票\字段]以及客户字段 用于理解字段和嵌套属性。
了解嵌套属性是如何工作的。这是最有意义的,也是我一直在寻找的。非常感谢。我必须解决老客户的选择问题,因为如果有任何大量数据,这显然是疯狂的。我不得不调整你的代码,在下拉列表中添加一个空格,否则它将始终自动选择一个旧客户,而不会使用:include\u blank=>true在选项的末尾\u from\u collection\u对于\u selectRight,我本应该考虑:include\u blank,但我忘了。不管怎样,很高兴你让它工作了。我感谢你的解释。比链接到一篇文章或一些宝石更有帮助。现在我明白了如何解决这个问题,我对未来充满信心,可以自信地开始寻找有助于解决此类问题的一个宝石。谢谢