Search code examples
ruby-on-railsrubyformsmodelsformtastic

Adding 4 Drinks to a Station in Form


I have two models: Stations & Drinks

Stations has_many :drinks and Drinks belongs_to :stations

I'm trying to make my form so that when you create a station, you can select 4 drinks that will belong to that station as well.

Original form:

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

I've been trying to figure out how to create 4 (select) input fields in this form so that you can select Drink #1, #2, #3, #4 for the current station. Any ideas?

I'm currently trying accepts_nested_attributes_for :drinks, :allow_destroy => true.

Drinks belongs_to :station

id | name | station_id |

Stations has_many :drinks

id | name |

.

UPDATE As noted below by tihm, you can add 4 drinks and edit their values with this:

<% 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 %>

However, what I'm trying to do is generate four select boxes that each list Drink.all and be able to swap out one drink object with a different one. So, when you change the value of the first select box from coke to pepsi, it removes the station_id from coke, and adds the station_id to pepsi.

I don't need to be able to edit the drink attributes.. I just need to change which drinks are associated with this station. Is this possible in the same form?


Solution

  • Unfortunately, I couldn't find a "best-practice" rails way of doing... so I ended up doing a bunch of AJAX / custom ruby code to implement it. Here it is (maybe it'll help someone else):

    <% @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>