views:

21

answers:

2

I have three models, booking, room and travellers.

Booking has many rooms room has many travellers

Since I'm doing a multi-step wizard booking and rooms gets created first, the travellers are created later in the update action.

This is the log for the update action: http://pastie.org/private/it7onlg8bnurqkgv6mptrq

And this is the relevant methods and actions for creating the travellers:

The view action

def step3
  @booking = Booking.find_by_random_url_key(params[:id])
  @variant = @booking.variant
  @booking.rooms.collect {|room| room.number_of_persons.times {room.travellers.build}  if room.travellers.blank?}
  render :partial => "bookings/partials/step3", :layout => "booking"
end

room.number_of_persons method just return an int.

Relevant part of the update action

..
elsif @booking.update_attributes(params[:booking]) && @booking.aasm_state == "step3"
  redirect_to booking_step4_url(@booking)
  @booking.next!
..

next! is just a aasm transition

If I do a create in the console

Room.last.travellers.create(:forename => "john", :country_name => "Germany")

Only one object is created and even if I go back in the view and submit again he correctly updates the created object and does not create new ones.

A: 
@booking.rooms.collect {|room| room.number_of_persons.times {room.travellers.build}  if room.travellers.blank?}

This looks wrong to me. You're initiating travellers but not storing them and collecting an array but not doing anything with it. Also, I understand you want to create a number of travellers but you condition on travellers being blank.

@travellers = @booking.rooms.collect { |room| room.number_of_persons.times { room.travellers.build } }
mark
I forgot to mention I'm using nested_attributes_for on both rooms and travellers. So the room.travellers.build builds the necessary objects in the form depending on how many number_of_persons a room has. The form picks up the build and generates the markup needed to display the fields for each traveller.
amunds