ruby-on-railsrubyhas-manybelongs-tocollection-select

Using collection_select for saving ID of two classes in a booking through has_many and belongs_to association throws error 'must exist' when saving


I am building a simple booking application for learning rails. I scaffolded people, cars and bookings.

Now when I try to create bookings I get

2 errors prohibited this booking from being saved:

  • Person must exist
  • Car must exist

Code

car.rb

class Car < ApplicationRecord
  has_many :bookings

  def brand_with_licence_plate
    "#{brand} #{licence_plate}"
  end

end

person.rb

class Person < ApplicationRecord
  has_many :bookings

  def complete_name
    "#{first_name} #{last_name}"
  end

end

bookings.rb

class Booking < ApplicationRecord
  belongs_to :Person
  belongs_to :Car
end

I added the columns for ID like so:

class AddItemsToBookings < ActiveRecord::Migration[6.1]
  def self.up
    add_column :bookings, :car_id, :integer
    add_column :bookings, :person_id, :integer
  end
end

I added to following to _form.html.erb

 <div class="field">
    <%= form.label :Person %>
    <%= form.collection_select(:person_id, Person.all, :id, :complete_name) %>
  </div>

  <div class="field">
    <%= form.label :Car %>
    <%= form.select :car_id, options_from_collection_for_select(Car.all, 'id','brand_with_licence_plate') %>
  </div>

and added to bookings_controller.rb

def booking_params
      params.require(:booking).permit(:start, :end, :person_id, :car_id)
end

I have looked here and tried to change to <%= form.select :car_id, options_from_collection_for_select(Car.all, 'id', 'brand_with_licence_plate') %> as stated in one answer, but giving me the same error.

When I look at the documentation everything seems to be fine as well.

It seems as if am missing something fundamental here. Any ideas how to fix this are appreciated.


Update:

I deleted the integer id column and run a new migration

class AddReferencesToBookingForPersonAndCar < ActiveRecord::Migration[6.1]
  def change
    add_reference :bookings, :people, foreign_key: true
    add_reference :bookings, :cars, foreign_key: true
  end
end

and adjusted the permissions for params as well.


Solution

  • You code doesn't look ok to me. I would change it like:

    class Booking < ApplicationRecord
      belongs_to :person
      belongs_to :car
    end
    

    Mainly, person and car are lower case. Also, I noticed that in your migration you create cars, in plural. It should be:

    class AddReferencesToBookingForPersonAndCar < ActiveRecord::Migration[6.1]
      def change
        add_reference :bookings, :person, foreign_key: true
        add_reference :bookings, :car, foreign_key: true
      end
    end
    

    belongs_to :car expects a car_id and it looks like that the migration is creating a cars_id instead.

    It would be easier to provide more help if you post the full controller code.