在表格中添加4种饮料到一个站

时间:2012-05-03 18:00:52

标签: ruby-on-rails ruby forms models formtastic

我有两种型号:Station&饮料

电台has_many:饮料和饮料属于:电台

我正在尝试制作我的表格,这样当你创建一个电台时,你也可以选择4种属于该电台的饮料。

原始形式:

<%= semantic_form_for [:admin, @station] do |f| %>
<fieldset class="inputs">
    <ol>
        <%=f.input :name %>
        <%=f.input :number, :as => :number %>
    </ol>
</fieldset>
<%= f.buttons :commit %>

我一直在试图弄清楚如何在这个表单中创建4个(选择)输入字段,以便您可以为当前电台选择Drink#1,#2,#3,#4。有任何想法吗?

我目前正在尝试accepts_nested_attributes_for :drinks, :allow_destroy => true.

饮品 belongs_to:station

id | name | station_id |

电台 has_many:drink

id | name |

更新 如下所述,您可以添加4种饮品并使用以下内容编辑其值:

<% f.fields_for :drinks do |drink_form| %>
            <%# Put your inputs here...could be a select box %>
            <%= drink_form.select :name, [['Drink #1', 'drink_1'],['Drink #2', drink_2] %>  

            <%# Or a plain input %>
            <%= drink_form.input :description %>  

            <%# ... Any other drink attributes ... %>
        <% end %>

然而,我正在尝试做的是生成四个选择框,每个框列出Drink.all并且能够将一个饮料对象换成另一个饮料对象。因此,当您将第一个选择框的值从焦炭更改为百事可乐时,它会从焦炭中移除station_id,并将station_id添加到百事可乐。

我不需要能够编辑饮料属性。我只需要更改与此电台相关的饮料。这可能是同一种形式吗?

2 个答案:

答案 0 :(得分:1)

你首先要看:

如果你知道你总是有4个或更少,那么它会更容易,你可以从Railscasts中跳过js。

在你的控制器中,一定要建立你需要的空饮料对象:

....
@station = Station.new
4.times do
  @station.drinks.build
end
...

这样,视图中的#fields_for就有了迭代的对象。在你看来,有些事情是:

<%= semantic_form_for [:admin, @station] do |f| %>
<fieldset class="inputs">
    <ol>
        <%=f.input :name %>
        <%=f.input :number, :as => :number %>
        <% f.fields_for :drinks do |drink_form| %>
            <%# Put your inputs here...could be a select box %>
            <%= drink_form.select :name, [['Drink #1', 'drink_1'],['Drink #2', drink_2] %>  

            <%# Or a plain input %>
            <%= drink_form.input :description %>  

            <%# ... Any other drink attributes ... %>
        <% end %>
    </ol>
</fieldset>
<%= f.buttons :commit %>

#select将在很大程度上取决于您从中选择的内容以及该数据的结构。它来自模型,简单列表等。

答案 1 :(得分:1)

不幸的是,我找不到“最佳实践”的做法......所以我最终做了一堆AJAX /自定义ruby代码来实现它。这是(也许它会帮助其他人):

<% @drinks = Drink.all %>
    <fieldset class="inputs">
        <ol>
        <% @station.drinks.each_with_index do |d,i| %>
            <li>
                <label class="label" for="station_name">Item</label>
                <%=select("drink", "id", @drinks.collect { |d| [d.name,d.id] }, {:include_blank => true, :selected => d.id}, {:class => "station-items"})%>
            </li>
        <% end %>
        <% m = 4-@station.drinks.count %>
        <% m.times do %>
            <li>
                <label class=" label" for="station_name">Item</label>
                <%=select("drink", "id", @drinks.collect { |d| [d.name,d.id] }, {:include_blank => true}, {:class => "station-items"})%>
            </li>
        <% end %>
        </ol>
    </fieldset>
    <%= f.buttons :commit %>
<% end %>

<script>    
$(".station-items").on("change",function(){
  var node = $(this)
  , prev = node.attr('data-rel')
  , next = parseInt(node.val())
  , station_id = $("#station_id").val()

  if(next) {
    $.ajax({
      url: "/drinks/"+next+".json",
      type: "PUT",
      data: { id:next, "drink[station_id]":station_id }
    });
  }

  if(prev) {
    $.ajax({
      url: "/drinks/"+prev+".json",
      type: "PUT",
      data: { id:prev, "drink[station_id]":"" }
    });
  }

  $(this).attr('data-rel',next);
});

$('.station-items option:selected').each(function(){
  return $(this).parent().attr('data-rel',$(this).val())
});
</script>