views:

237

answers:

1

I have a set of nested models for storing prices for individual rooms.

Ie.

  Places
    Rooms
      Room_rates

Each model has the necessary accepts_nested_attributes_for and has_many belongs_to association and I have a form and a build method which works perfectly for the initial creation.

My question is how to make a smarter controller, that either builds the field if it doesn't exist, or reads from it if it does (and doesn't build it). Currently it only works for the initial input, otherwise it attempts to build more fields than are possible and breaks on resubmission.

  def new
    @place = Place.find(params[:place_id])
    @rooms = @place.rooms

    @rooms.each do |r|
      7.times { r.room_rates.build } #days of the week
    end

  end

tried

@rooms.each do |r|
  7.times { 
    unless r.room_rates
      r.room_rates.build
    end 
  }
end

database for room_rates

id, room_id, dayofweek, price

form

<% form_for @place do |f| %>
  <%= f.error_messages %>


<table>
  <tr>  
    <th>Room</th>
    <th>Mon</th>
    <th>Tue</th>
    <th>Wed</th>
    <th>Thu</th>
    <th>Fri</th>
    <th>Sat</th>
    <th>Sun</th>
  </tr>
  <% f.fields_for :rooms do |room| %>
    <% dow = 0 %>
      <tr>
        <td><%= room.text_field :name %></td>

        <% room.fields_for :room_rates do |rates| %>

            <td>    
                <%= rates.text_field :price %>
                <%= rates.text_field :dayofweek, :value => dow %>   
            </td>
            <% dow += 1 %>
        <% end %>
      </tr>
  <% end %>
</table>

<%= f.submit "Submit" %>

<% end %>
+1  A: 

You can try:

@rooms.each do |r|
  ((r.room_rates.size+1)..7).each {   
      r.room_rates.build       
  }
end
klew
That seems to work well... however this doesn't map them properly on edit. If someone only updates one field in the row, it saves and saves it properly, however when it reloads it shows it in the incorrect position? Instead of being in column Wednesday it shows up in field Monday, even though the database shows it correctly. It doesn't have this problem if exactly none of the fields in a row are blank.
holden
Somehow the loop has to order them by their position in the week? and I'm not sure how to do this.
holden
I think you have here some bad design problem. For me it looks bad if you need to have exactly 7 rows with prices for each room. It would work if you would build `room_rates` when you build `room`, so when it will iterate over `room_rates` there will always be monday even if the price is `nil`. I would add columns like `monday_price`, `tuesday_price` to room model or in seperate model which stores prices for whole week. It will be much easier in every case.
klew