Skip to content

Model Relationships

FluentBooking database tables are interconnected via primary and foreign key relationships. Our ORM makes managing these relationships effortless.

Relationship Types

  • One-to-Many (HasMany): A Calendar has many Events. A Booking has many BookingMeta records.
  • Many-to-Many (BelongsToMany): A Booking has many Hosts (via fcal_booking_hosts pivot table).
  • Inverse One-to-Many (BelongsTo): A CalendarSlot belongs to a Calendar. An Order belongs to a Booking.
  • One-to-One (HasOne): An Order has one Transaction.

Core Model Relationships

Parent ModelRelationTypeChild ModelForeign Key
Calendarevents / slotsHasManyCalendarSlotcalendar_id
CalendarbookingsHasManyBookingcalendar_id
CalendaruserBelongsToUseruser_id
CalendaravailabilitiesHasManyAvailabilityobject_id (user_id)
CalendarmetasHasManyMetaobject_id (where object_type = 'Calendar')
CalendarSlotcalendarBelongsToCalendarcalendar_id
CalendarSlotbookingsHasManyBookingevent_id
CalendarSlotuserBelongsToUseruser_id
CalendarSlotevent_metasHasManyMetaobject_id (where object_type in calendar_event, integration)
BookingcalendarBelongsToCalendarcalendar_id
Bookingslot / calendar_eventBelongsToCalendarSlotevent_id
BookinguserBelongsToUserhost_user_id
BookinghostsBelongsToManyUservia fcal_booking_hosts pivot
Bookingbooking_metaHasManyBookingMetabooking_id
Bookingbooking_activitiesHasManyBookingActivitybooking_id
Bookingpayment_orderHasOneOrderparent_id (Pro)
UsercalendarsHasManyCalendaruser_id
BookingActivitybookingBelongsToBookingbooking_id
BookingHostbookingBelongsToBookingbooking_id
BookingMetabookingBelongsToBookingbooking_id
OrderbookingBelongsToBookingparent_id (Pro)
OrdertransactionHasOneTransactionsobject_id (Pro)
OrderitemsHasManyOrderItemsorder_id (Pro)
OrderdiscountsHasManyOrderItemsorder_id (where type = 'discount') (Pro)

Relationship Best Practices

1. Use Eager Loading

Avoid "N+1" query problems by using the with() method to load relationships in a single batch.

php
// Good: Loads 10 bookings and their calendars in 2 queries
$bookings = Booking::with('calendar')->limit(10)->get();

foreach ($bookings as $booking) {
    echo $booking->calendar->title;
}

2. Relationship Constraints

You can filter a query based on the existence or properties of a relationship.

php
// Get all calendars that have at least one active booking
$calendars = Calendar::has('bookings')->get();

// Get bookings for a specific event slug
$bookings = Booking::whereHas('calendar_event', function($query) {
    $query->where('slug', '15-min-meeting');
})->get();

Performance Considerations

  1. Index Foreign Keys: All relationship columns (like calendar_id, event_id, user_id) are indexed in the fcal_ tables to ensure rapid joins.
  2. Select Specific Columns: When eager loading, you can specify exactly which columns to retrieve to save memory.
    php
    $bookings = Booking::with('calendar:id,title,slug')->get();
  3. Lazy Loading Caution: Accessing $booking->calendar without eager loading triggers a separate database query for every instance. Use this only for single-record views.