Skip to main content
Tickets connect attendees to events. When a user purchases tickets for an event, Eventify creates a ticket record, deducts the requested quantity from the event’s remaining capacity, and increments the attendee count — all in a single atomic operation. If the purchase brings capacity to zero, the event is automatically marked as sold out.

Ticket Model Fields

Ticket records are stored in the tickets table, created by the following migration:
bigint
required
Auto-incrementing primary key.
bigint
required
Foreign key referencing the users table. Identifies the purchaser.
bigint
required
Foreign key referencing the events table. Identifies the event the ticket is for.
integer
required
Number of individual tickets purchased in this transaction.
timestamp
Populated by Laravel’s soft-delete mechanism when a ticket record is soft-deleted. null for active tickets.

Purchasing Tickets

Tickets are purchased by submitting a form on the event detail page to:
This route is protected by the auth middleware — users must be logged in to purchase tickets. The purchase flow handled by TicketController::store() runs as follows:
1

Locate the event

The controller retrieves the target event using the event_id from the request:
2

Enforce capacity

Before creating any record, the controller validates that the requested quantity can be fulfilled:
If the event has no remaining capacity, or the requested quantity exceeds what’s left, the request is rejected and the user is redirected back with an error message.
3

Create the ticket record

A new Ticket is instantiated and saved with the quantity, event ID, and the authenticated user’s ID:
4

Update event capacity and attendance

The event’s capacity is decremented and attendees is incremented by the purchased quantity:
5

Mark as sold out if needed

If the purchase brings capacity exactly to zero, the event’s status is automatically changed to Agotado (status_id = 2):
6

Redirect with confirmation

The user is redirected back to the event page with a success message:

Capacity Enforcement

The capacity check is the central guard that prevents overselling. The condition covers two distinct failure scenarios:
The capacity check does not use a database-level lock. In high-concurrency scenarios, two users submitting requests simultaneously could both pass the check before either write completes. For production deployments with high-demand events, consider wrapping the purchase logic in a database transaction with a pessimistic lock (e.g., lockForUpdate()).

My Tickets Dashboard

Authenticated users can view all their ticket purchases at:
The TicketController::showMyTickets() method returns tickets belonging to the currently authenticated user, ordered from most recent to oldest:
Each ticket in the list is linked to its parent event via the event relationship, giving the view access to the event name, dates, location, and price for display.

PDF Ticket Report

Each ticket purchase can be downloaded as a PDF. The report is generated on demand at:
The TicketController::generateTicket() method loads the full ticket with its associated event and user, parses the event dates using Carbon, calculates the total cost, and renders a Blade view as a downloadable PDF:
The generated PDF (ticket.pdf) includes:
  • Event name, start date, and end date (Carbon-formatted)
  • Ticket quantity
  • Per-ticket price and calculated total
  • Purchasing user details
Ticket editing and deletion are not supported through the UI. The edit, update, and destroy methods exist as stubs in TicketController but contain no implementation. Only purchasing (via store) and PDF download (via generateTicket) are available to end users.

Relationships

The Ticket model declares the following Eloquent relationships:

User

The authenticated user who purchased the ticket. Used on the dashboard to scope each user’s ticket list.

Event

The event the ticket is for. Eagerly loaded when generating the PDF report to provide name, dates, price, and location.