繁体   English   中英

Rails:使用嵌套表单同时保存父级和子级

[英]Rails: Saving Parent and Child simultaneously with nested forms

我有一个Event模型和一个Packages模型:

# event.rb
belongs_to :organization, optional: true
belongs_to :event_type, optional: true

has_many :packages

has_many :collaborations
has_many :messages, through: :collaborations
has_many :forms, through: :collaborations

# package.rb
belongs_to :event

has_many :package_collaborations
has_many :collaborations, through: :package_collaborations

我希望用户能够使用嵌套的表单同时创建一个Event和Packages:

[图片]

这是我的两种形式:

#_event_form.rb (simplified for easier reading)
<%= form_for(event) do |f| %>

  <%= render 'shared/error_messages', object: f.object %>
  <br>
  <div class="form-group">
    <%= f.label :title %>
    <%= f.text_field :title, class: 'form-control' %>
  </div>

<% if f.object.new_record? %>
  <%= f.hidden_field :status, value: 'upcoming' %>
<% else %>
  <div class="form-group">
    <%= f.label :attendee_count %>
    <%= f.number_field :attendee_count, class: 'form-control' %>
  </div>
  <div class="form-group">
    <%= f.label :status %>
    <%= f.select :status, [['Upcoming','upcoming'],['Completed','completed']], {}, class: 'form-control' %>
  </div>
<% end %>

  <hr>

  <div class="form-group required">
    <%= f.label :started_at, 'Starts' %>
    <div class='input-group date form_datetime'>
      <% if event.started_at.present? %>
        <%= f.text_field :started_at, class: 'form-control', value: event.started_at.strftime("%m/%d/%Y %H:%M %p") %>
      <% end %>
    </div>
  </div>

  <div class="form-group required">
    <%= f.label :ended_at, 'Ends' %>
    <div class='input-group date form_datetime'>
      <% if event.ended_at.present? %>
        <%= f.text_field :ended_at, class: 'form-control', value: event.ended_at.strftime("%m/%d/%Y %H:%M %p") %>
      <% end %>
    </span>
    </div>
  </div>

  <%= f.hidden_field :platform_type, value: "a_platform" %>

  <hr>
  <%= render 'packages/package_form', event: @event %> # <--- Nested form here.

  <div class="actions" id="listen-for-hover">
    <%= f.submit 'Save', class: 'btn btn-primary', :id => "event-create-button"  %>
  </div>
<% end %>


#_package_form.rb
<%= form_for([@event, @package]) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>

  <%= f.hidden_field :kind, value: params[:kind] if f.object.new_record? %>

  <div class="form-group required">
    <%= f.label :Your_offer_?, "Your Offer?" %>
    <%= f.text_area :offering, class: 'form-control', :placeholder => "e.g. Your logo on stuff" %>
  </div>

  <div class="form-group">
    <%= f.label :notes %>
    <%= f.text_area :notes, class: 'form-control', :placeholder => "Notes here"  %>
  </div>

  <hr>

  <div class="actions">
    <%= f.submit 'Submit', class: 'btn btn-primary', id: 'package-submit-button', disabled: true %>
  </div>
<% end %>

以这种方式使用表单会导致此错误:

Extracted source (around line #3):
1  <%# remoteFlag = false %>
2  <%# remoteFlag = true if @event.title == "dummy event" %>
3  <%= form_for([@event, @package]) do |f| %>
4    <%= render 'shared/error_messages', object: f.object %>

显然这是因为还没有创建@event所以没有它的ID。 制作这个嵌套表单的最佳方法是用于同时创建新事件/包(没有ID的新对象)或使用部分另一部分编辑现有(带有ID的现有对象)应用程序吗?

您可以使用'build'方法在'event'中创建一个空的'package'。 官方RoR指南中有一个例子

例如

<%= form_for([@event, @event.packages.build]) do |f| %>

你需要添加

accepts_nested_attributes_for :package

到您的事件模型(在event.rb中)。 然后,在事件控制器的“新”方法中,添加

@package = @event.packages.build

在表单中,您需要使用fields_for方法。 这整个过程有一个很好的Railscast: http//railscasts.com/episodes/196-nested-model-form-part-1如果你不熟悉Ryan Bates的Railscasts,我强烈建议你花点钱与他们共度时光。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM