2015-04-29 190 views
1

我想创建一个具有这种格式的表格:多个记录

Shared Fields 
Fields Unique to record A 
[add another record button] 

凡[添加]按钮,可以点击多次,有必要建立

Shared Fields 
Fields Unique to record A 
Fields Unique to record B 
Fields Unique to record C 
[add another record button] 

提交表单创建记录A,B和C

后端

这将创建3条记录,每条记录都具有与表单中的字段一样的共享和唯一属性。

更新共享

的一件事是他们各自所属的“雇主”。所以这应该是一个form_for @employer?

大声思考,我们可以在父级上保存共享属性attr_accessors,并将它们分配给子级控制器的“child#create”动作中的子级。

+0

你描述的前端,对背什么结束?应该填写什么数据? –

+0

更新后的描述 –

+1

我对你的术语有些困惑。当你说“模型”时,你的意思是“模型类的记录/实例”吗? –

回答

2

既然你在多个模型填写一个表格嵌套不,你不能只是生成form_for @something的形式,因为你有没有单一的对象让我们填写。

我会检讨数据库结构来查看是否有办法将共享字段提取为独立模型。但是如果没有办法做到这一点,请继续阅读。

用于呈现对象表单的Rails帮助器以Rails可以正确解析为散列的方式布局字段。反过来,这又可以用来构建一个对象。通过使用这样的:

form_for @thing do |f| 
    t.text_field :name 
end 

你会得到一个形式thing[name]领域,这将看在params像这样:

{..., thing: {name: "Hello world"}, ...} 

更多这方面的详细信息,请参见the guides

现在这里是捕获:你没有一个单一的对象来填补,但你可以忽略这一点,并建立一个仍然可以解析为嵌套哈希的形式。你只需要手工填写Rails另外猜测的内容:表单URL和对象名称。

form_for :thing, url: thing_path do |f| 
    f.text_field :name 
end 

如果要创建一组字段,请在此表单中使用fields_for帮助程序。更多信息in the documentation,形式也可能是这样的:

form_for :thing, url: thing_url do |f| 
    f.text_field :name 
    f.fields_for :something do |s| 
    s.text_field :value 
    end 
end 

这应该渲染会被解析为一个单一的哈希一个字段。但您可能需要一组嵌套的字段集,请参阅文档。

最终你会得到:

  • 哈希
    • 共享参数
    • Array对象的
    • 对象A
    • 对象A
    • 对象B
    • ...

,现在你需要添加字段通过JavaScript的形式,但应提前加什么标记知道最终的问题–。有很多方法可以解决这个问题,其中一个就是为每个独特的模型渲染一个示例表单并使用JavaScript对其进行采样。

编辑:巧合的是,我需要找出如何呈现一个“裸”(没有被对象支持)形式,可以由JavaScript被复制和将如下对象中的参数的阵列,当多个形式是给出。

棘手的部分是,如果您使用fields_for :something,它将产生一个表单,而不是其中的一个数组。挖掘周围,我发现了一个看似没有记录的功能(围绕this post的代码挖掘)。它这样使用(我使用HAML为了简洁/修身语法):

= form_for :thing, url: whatever do |f| 
    = f.fields_for :stuff, index: '' do |s| #<< the `index: ''` part 
    = s.text_field :v 

语义这似乎意味着以下几点:做一个包含场stuff形式,填充在由一个或多个字段集与空索引。引擎盖下,它第一眼产生一个有点尴尬的字段名称:(?甚至机架)

thing[stuff][v] # Before, without ` index: '' ` 
thing[stuff][][v] # After, see the empty index? 

的这个有趣的部分是,你可以只克隆resultig字段集,而无需修改它,Rails会将这组表单分解成单独的对象。这依赖于浏览器保留字段的顺序,这在大多数情况下是正确的。

0

在你new.html.erb

<div id="formDiv"> 
    <%= form_for @user do |f| %> 
    <%= render 'shared/error_messages' %><br> 
    <%= f.label :name %><br> 
    <%= f.text_field :name %><br> 
    <%= f.label :email %><br> 
    <%= f.email_field :email %><br> 
    <%= f.label :password %><br> 
    <%= f.password_field :password %><br> 
    <%= f.label :password_confirmation, "Confirmation" %><br> 
    <%= f.password_field :password_confirmation %><br> 
    <%= f.submit "Create my account", class: "btn btn-primary" %> 
    <% end %> 
    <input id="add" type="submit" value="Add"/> 
</div> 
<script> 
$("#add").click(function() { 
    $.ajax({ 
    url: "newAjax", 
    success: function (html) { 
     $("#formDiv").append(html); 
    } 
    }); 
}); 
$('form').submit(function(){ 
    $('.multiform').each(function() { 
    $(this).submit(); 
    }); 
    return true; 
}); 
</script> 

此使用AJAX每次添加一个新的表格,您通过其他形式单击该按钮,当您尝试提交表单,它周期, “multiform”类并首先提交它们。

在你newAjax.html.erb

<%= form_for @user, remote: true, html: { class: 'multiForm' } do |f| %> 
<%= f.label :name %><br> 
    <%= f.text_field :name %><br> 
    <%= f.label :email %><br> 
    <%= f.email_field :email %><br> 
    <%= f.label :password %><br> 
    <%= f.password_field :password %><br> 
    <%= f.label :password_confirmation, "Confirmation" %><br> 
    <%= f.password_field :password_confirmation %><br> 
<% end %> 

我们使用AJAX以这种形式,使他们能够在不重定向提交。 而去年在控制器

def newAjax 
    @user = User.new 
    render :layout => false 
end 

我们要确保我们的布局不与AJAX的形式呈现的,所以我们不刷新你的JS/CSS文件等

0

这是我使用的工作代码到底。感谢所有帮助过的人。遵循D方的方法,但使用“雇主”作为基础模型。我可以重构这个来删除Employer上的attr_accessors,而是在视图中使用字段标记。最后,我只是从传递给控制器​​的“params”数组中取出共享值。

预订控制器:

def new 
    @employer = current_employer 
    @booking = @employer.bookings.build 
    respond_with(@booking) 
    end 

    def create 
    errors = [] 
    booking_create_params["new_booking_attributes"].each do |booking| 
     new_booking = current_employer.bookings.build(booking) 
     new_booking.job_type_id = booking_create_params["job_type_id"] 
     new_booking.vehicle_id = booking_create_params["vehicle_id"] 
     new_booking.location_id = booking_create_params["location_id"] 
     new_booking.pay = booking_create_params["pay"] 
     unless new_booking.save 
     errors << new_booking.errors.full_messages 
     end 
    end 

    if errors == [] 
     flash[:notice] = "Bookings posted!" 
     redirect_to new_booking_path 
    else 
     flash[:notice] = "Error: #{errors.join(', ')}!" 
     redirect_to new_booking_path 
    end 
    end 

在视图:

<div id="bookings"> 
     <ol class="numbers"> 
     <li> 
      <legend>Location, Pay, & Vehicle</legend> 

      <div class="form-group"> 
      <div class="row"> 
       <div class="col-sm-6"> 
       <label>Type of job</label><br> 
       <%= f.select(:job_type_id, options_from_collection_for_select(JobType.all, :id, :name_with_delivery), {}, { id: 'job-type', class: 'form-control' }) %> 
       </div> 
       <div class="col-sm-6"> 
       <label>Vehicle needed</label><br> 
       <%= f.select(:vehicle_id, options_from_collection_for_select(Vehicle.all, :id, :name), {}, { id: 'vehicle-type', class: 'form-control' }) %> 
       </div> 
      </div> 
      </div> 

      <div class="form-group"> 
      <div class="row"> 
       <div class="col-sm-6"> 
       <label>Location</label> 
       <% if current_employer.locations.count > 1 %> 
        <%= f.select :location_id, options_from_collection_for_select(current_employer.locations.all, :id, :name_or_address_1), {}, { class: 'form-control' } %> 
       <% elsif current_employer.locations.count == 1 %> 
        <p><strong>Location: </strong><%= current_employer.locations.first.name_or_address_1 %></p> 
        <%= f.hidden_field :location_id, current_employer.locations.first.id %> 
       <% end %> 
       <%= link_to "or add new location", new_employer_location_path(current_employer, Location.new) %> 
       </div> 
       <div class="col-sm-6"> 
       <%= f.label :pay %><br> 
       <%= f.text_field :pay, class: 'form-control' %> 
       </div> 
      </div> 
      </div> 

     </li> 
     <legend>Shifts</legend> 
     <%= render 'booking', booking: Booking.new %> 
     </ol> 
    </div> 

其中部分是:

<li class="close-list-item"> 

<!-- Recommended: post at least 1 week in advance 
    & shift length at least 4 hours. 
    --> 
    <% new_or_existing = booking.new_record? ? 'new' : 'existing' %> 
    <% prefix = "employer[#{new_or_existing}_booking_attributes][]" %> 
    <%= fields_for prefix, booking do |booking_form| -%> 

    <div class="shifts"> 
    <div class="form-group shift"> 
     <div class="row"> 
     <div class="col-sm-4"> 
      <label for="">Date</label> 
      <i class="glyphicon glyphicon-time"></i> 
      <%= booking_form.text_field :start, class: 'form-control booking-date', placeholder: 'Date', data: { provide: "datepicker", date_clear_btn: "true", date_autoclose: "true", date_start_date: '+1d', date_format: "yyyy-mm-dd" } %>     
     </div> 
     <div class="col-sm-4"> 
      <label>Time Start</label><br> 
      <%= booking_form.select(:start_time, options_for_select(
      booking_times_array 
     ), { include_blank: true }, { class: 'form-control booking-time booking-time-start' }) %> 
     </div> 
     <div class="col-sm-4"> 
      <label> 
      Time End 
      </label> 
      <%= link_to "javascript:;", class: 'pull-right remove-shift' do %> 
       <i class="glyphicon glyphicon-remove"></i> 
      <% end %> 
      <script type="text/javascript"> 
       $(".remove-shift").click(function(){ 
       $(this).parents("li").remove(); 
       }); 
      </script> 
      <%= booking_form.select(:end_time, options_for_select(
      booking_times_array 
     ), { include_blank: true }, { class: 'form-control booking-time booking-time-end' }) %> 
     </div> 
     </div> 
    </div> 
    </div> 
</li> 
<% end -%> 
+0

不客气!顺便更新了我最近的调查结果。不能停止想知道为什么。 :d –