Search code examples
ruby-on-railsformsnested-formsnested-attributeshas-many-through

Rails has_many through join model undefined id: "undefined method `attributes' for #" when submitting nested form


I am getting a 'NoMethodError' when trying to submit a nested rails form. The form is used to create a reservation, and a serviceType - reservation (The join model).

The error I get is "undefined method `attributes' for #"

This is my reservations model: reservation.rb

module Booking
 class Reservation < ActiveRecord::Base
  has_many :service_type_reservations, inverse_of: :reservation, dependent: :destroy
  accepts_nested_attributes_for :service_type_reservations, allow_destroy: true

  has_many :service_types, through: :service_type_reservations, dependent: :destroy
  has_one :customer_reservation, dependent: :destroy
  has_one :customer, through: :customer_reservation, dependent: :destroy

  validates_uniqueness_of :service_type_reservations
 end
end

This is the servicetype-reservation model: servicetypereservation.rb

module Booking
 class ServiceTypeReservation < ActiveRecord::Base
  belongs_to :service_type
  belongs_to :reservation
  belongs_to :service_calendar

  validates :reservation, presence: true
  validates :service_type, presence: true
 end
end

In my reservations controller, these are the new and create functions: reservations_controller.rb

# GET /reservations/new
def new
  @serviceTypes = ServiceType.all
  @reservation = Reservation.new
  @reservation.build_service_type_reservations
  @numberOfServices = @serviceTypes.length
  if params[:service_type_id]
    @selectedService = ServiceType.find(params[:service_type_id])
  end
end

# POST /reservations
def create
  @serviceTypes = ServiceType.all
  @reservation = Reservation.new(reservation_params)

  if @reservation.save
    redirect_to new_customer_path(reservation_id: @reservation.id), notice: 'Reservation was successfully created.'
  else
    render :new
  end
end

This is the reservations params in the reservations controller:

# Only allow a trusted parameter "white list" through.
  def reservation_params
    respond_to do |format|
      format.html { params.require(:reservation).permit(:updated_at, :created_at, :total_price, :customer_id, service_type_reservations_attributes: [:occupancy, :check_in, :check_out, :date, :service_type_id])}
    end
  end

To create the nested form:

<%= form_for(@reservation) do |f| %>
   <%= f.fields_for :service_type_reservations do |service_reservation_form| %>

I'm pretty sure it's creating a new service type reservation but it has an undefined id. I'm not sure if the id is that attribute though. I have tried changing the code a bit and have gotten the error "undefined attribute '0'" so I'm pretty sure it's the id.

When I create the reservation (and the servicetype-reservation), doesn't it automatically generate an id already? (It usually does in rails..).

Any help would be appreciated. Thanks!


Solution

  • I removed the line

    validates_uniqueness_of :service_type_reservations
    

    from reservations.rb

    The form can now be submitted. There was an error without this line before but it suddenly started working. I think I just needed to restart the server.