Добавление 4 напитков на станцию ​​в форме

У меня две модели: Stations & Drinks

Станции has_many :drinks и напитки, принадлежащие_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.

Напитки принадлежит :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 к пепси.

Мне не нужно редактировать атрибуты напитков. Мне просто нужно изменить, какие напитки связаны с этой станцией. Возможно ли это в той же форме?


person Brian Weinreich    schedule 03.05.2012    source источник


Ответы (2)


Вы можете начать с просмотра:

Если вы знаете, что у вас всегда будет 4 или меньше, тогда это немного проще, и вы можете пропустить js из Railscasts.

В вашем контроллере обязательно создайте нужные вам пустые объекты напитка:

....
@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 будет во многом зависеть от того, что вы выбираете, и структуры этих данных. Это исходит от модели, простого списка и т. Д.

person tihm    schedule 03.05.2012
comment
Это хорошо работало для обычного приложения Rails. Кроме того, если кто-то ищет решение для использования с Active Admin (которое мне также нужно): github .com/gregbell/active_admin/issues/59 решил проблему. - person Brian Weinreich; 03.05.2012
comment
Хорошо, сначала я подумал, что это то, что мне нужно. Однако это немного сложнее. То, что вы указали выше, позволяет мне редактировать содержимое (название, описание и т. д.) 4 напитков, связанных со станцией. Однако мне нужно иметь возможность поменять НАСТОЯЩИЙ напиток в точке №1. Так, например, вместо того, чтобы редактировать название напитка № 1 с пепси на кока-колу, мне нужно изменить название напитка с объекта пепси на объект кока-колы. - person Brian Weinreich; 04.05.2012

К сожалению, я не смог найти «наилучший» способ работы с рельсами... поэтому я закончил тем, что сделал кучу AJAX/собственного рубинового кода для его реализации. Вот (может кому еще пригодится):

<% @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 = [email protected] %>
        <% 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>
person Brian Weinreich    schedule 07.05.2012