2

我有两个模型:Station & Drinks

车站 has_many :drinks and Drinks belongs_to :stations

我正在尝试制作我的表格,以便当您创建一个站点时,您可以选择 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 个(选择)输入字段,以便您可以为当前站选择饮料 #1、#2、#3、#4。有任何想法吗?

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

饮料belongs_to :station

id | name | station_id |

车站has_many :drinks

id | name |

.

更新 如下 tihm 所述,您可以添加 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 添加到百事可乐。

我不需要能够编辑饮料属性。我只需要更改与该站点关联的饮料。这可能以相同的形式出现吗?

4

2 回答 2

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 在很大程度上取决于您选择的内容以及该数据的结构。它来自模型、简单列表等吗?

于 2012-05-03T18:09:43.053 回答
1

不幸的是,我找不到“最佳实践”的 rails 方式......所以我最终做了一堆 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>
于 2012-05-07T17:47:35.260 回答