Skip to Content
v2DeveloperData Models

Last Updated: 3/11/2026


Data Models

LinkAce is built on Laravel and uses Eloquent ORM for database interactions. This guide covers the core data models and their relationships.

Core Models

The Link model represents a bookmarked URL with metadata and status tracking.

Database Table: links

Properties:

  • id (int) - Primary key
  • user_id (int) - Foreign key to User
  • url (string) - The bookmarked URL
  • title (string) - Link title
  • description (string|null) - Optional description
  • icon (string|null) - Icon identifier
  • visibility (int) - 1=Private, 2=Internal, 3=Public
  • status (int) - 1=OK, 2=Moved, 3=Broken
  • check_disabled (boolean) - Whether link checking is disabled
  • last_checked_at (datetime|null) - Last check timestamp
  • thumbnail (string|null) - Thumbnail URL
  • created_at (datetime) - Creation timestamp
  • updated_at (datetime) - Last update timestamp
  • deleted_at (datetime|null) - Soft delete timestamp

Relationships:

  • user() - BelongsTo User (with trashed)
  • lists() - BelongsToMany LinkList (via link_lists pivot table)
  • tags() - BelongsToMany Tag (via link_tags pivot table)
  • notes() - HasMany Note
  • audits() - MorphMany (audit trail)

Status Constants:

Link::STATUS_OK = 1; // Link is accessible Link::STATUS_MOVED = 2; // Link redirects Link::STATUS_BROKEN = 3; // Link is inaccessible

Display Constants:

Link::DISPLAY_CARDS = 1; // Card view Link::DISPLAY_LIST_SIMPLE = 2; // Simple list view Link::DISPLAY_LIST_DETAILED = 3; // Detailed list view

Key Methods:

  • getFormattedDescriptionAttribute() - Returns markdown-formatted description
  • shortUrl() - Returns URL without https:// prefix
  • shortTitle(int $maxLength = 50) - Returns truncated title
  • domainOfURL() - Extracts domain from URL
  • getIcon(string $additionalClasses = '') - Returns icon HTML
  • addedAt() - Returns formatted creation date HTML
  • initiateInternetArchiveBackup() - Dispatches Wayback Machine backup job
  • searchDuplicateUrls() - Finds potential duplicate URLs

Scopes:

  • byUser(int $user_id = null) - Filter by user
  • privateOnly() - Only private links
  • internalOnly() - Only internal links
  • publicOnly() - Only public links

Allowed Order By Fields: id, url, title, description, visibility, status, check_disabled, created_at, updated_at, random

The LinkList model represents a collection of links organized by the user.

Database Table: lists

Properties:

  • id (int) - Primary key
  • user_id (int) - Foreign key to User
  • name (string) - List name
  • description (string|null) - Optional description
  • visibility (int) - 1=Private, 2=Internal, 3=Public
  • created_at (datetime) - Creation timestamp
  • updated_at (datetime) - Last update timestamp
  • deleted_at (datetime|null) - Soft delete timestamp

Relationships:

  • user() - BelongsTo User (with trashed)
  • links() - BelongsToMany Link (via link_lists pivot table)

Key Methods:

  • getFormattedDescriptionAttribute() - Returns markdown-formatted description

Scopes:

  • byUser(int $user_id = null) - Filter by user
  • privateOnly() - Only private lists
  • internalOnly() - Only internal lists
  • publicOnly() - Only public lists

Allowed Order By Fields: id, name, description, visibility, created_at, updated_at, random, links_count

Global Scope: Automatically ordered by name (OrderNameScope)

Tag

The Tag model represents a label that can be attached to links for categorization.

Database Table: tags

Properties:

  • id (int) - Primary key
  • user_id (int) - Foreign key to User
  • name (string) - Tag name
  • visibility (int) - 1=Private, 2=Internal, 3=Public
  • created_at (datetime) - Creation timestamp
  • updated_at (datetime) - Last update timestamp
  • deleted_at (datetime|null) - Soft delete timestamp

Relationships:

  • user() - BelongsTo User (with trashed)
  • links() - BelongsToMany Link (via link_tags pivot table)

Scopes:

  • byUser(int $user_id = null) - Filter by user
  • privateOnly() - Only private tags
  • internalOnly() - Only internal tags
  • publicOnly() - Only public tags

Allowed Order By Fields: id, name, description, visibility, created_at, updated_at, random, links_count

Global Scope: Automatically ordered by name (OrderNameScope)

Note

The Note model represents a user note attached to a link.

Database Table: notes

Properties:

  • id (int) - Primary key
  • link_id (int) - Foreign key to Link
  • user_id (int) - Foreign key to User
  • note (text) - Note content
  • visibility (int) - 1=Private, 2=Internal, 3=Public
  • created_at (datetime) - Creation timestamp
  • updated_at (datetime) - Last update timestamp

Relationships:

  • link() - BelongsTo Link
  • user() - BelongsTo User (with trashed)

User

The User model represents a LinkAce user account.

Database Table: users

Properties:

  • id (int) - Primary key
  • name (string) - User’s display name
  • email (string) - Email address (unique)
  • email_verified_at (datetime|null) - Email verification timestamp
  • password (string) - Hashed password
  • remember_token (string|null) - Remember me token
  • created_at (datetime) - Creation timestamp
  • updated_at (datetime) - Last update timestamp
  • deleted_at (datetime|null) - Soft delete timestamp

Relationships:

  • links() - HasMany Link
  • lists() - HasMany LinkList
  • tags() - HasMany Tag
  • notes() - HasMany Note
  • tokens() - HasMany API tokens (Sanctum)

UserInvitation

The UserInvitation model represents an invitation to join LinkAce.

Database Table: user_invitations

Properties:

  • id (int) - Primary key
  • email (string) - Invitee email address
  • token (string) - Invitation token (unique)
  • created_by (int) - User ID who created the invitation
  • used_at (datetime|null) - When invitation was used
  • created_at (datetime) - Creation timestamp
  • updated_at (datetime) - Last update timestamp

Visibility System

All content models (Link, LinkList, Tag, Note) support a three-tier visibility system:

Visibility Levels

  1. Private (1) - Only visible to the owner
  2. Internal (2) - Visible to all authenticated users in the instance
  3. Public (3) - Visible to everyone, including unauthenticated guests

Implementation

Visibility is implemented through:

  • The ModelAttribute::VISIBILITY_* enum constants
  • The ScopesVisibility trait providing query scopes:
    • privateOnly() - Filter to private items only
    • internalOnly() - Filter to internal items only
    • publicOnly() - Filter to public items only

User Scoping

All content models implement user-based scoping through the ScopesForUser trait:

// Get links for a specific user $links = Link::byUser($userId)->get(); // Get links for the current authenticated user $links = Link::byUser()->get();

Soft Deletes

All content models use Laravel’s soft delete feature:

  • Deleted items are marked with a deleted_at timestamp
  • Items remain in the database but are excluded from normal queries
  • Deleted items can be restored or permanently deleted
  • Trash endpoints provide access to soft-deleted items

Auditing

LinkAce uses the owen-it/laravel-auditing package to track changes:

  • All content models implement the Auditable interface
  • Changes are logged to the audits table
  • Audit modifiers transform field values for readability:
    • VisibilityModifier - Converts visibility integers to labels
    • BooleanModifier - Converts booleans to Yes/No
    • LinkStatusModifier - Converts status integers to labels
    • TagRelationModifier - Tracks tag relationship changes
    • ListRelationModifier - Tracks list relationship changes

Pivot Tables

Joins links and lists in a many-to-many relationship.

Columns:

  • link_id (int) - Foreign key to links
  • list_id (int) - Foreign key to lists

Joins links and tags in a many-to-many relationship.

Columns:

  • link_id (int) - Foreign key to links
  • tag_id (int) - Foreign key to tags

Model Attributes Enum

The ModelAttribute enum defines constants used across models:

ModelAttribute::VISIBILITY_PRIVATE = 1; ModelAttribute::VISIBILITY_INTERNAL = 2; ModelAttribute::VISIBILITY_PUBLIC = 3;

Database Schema

Supported Databases

LinkAce supports:

  • MySQL 8.0+
  • PostgreSQL 12+
  • SQLite 3.35+

Migrations

Database migrations are located in database/migrations/. Key migrations include:

  • User and authentication tables
  • Core content tables (links, lists, tags, notes)
  • Pivot tables for relationships
  • Settings and configuration tables
  • Audit tables

Collation

For MySQL/MariaDB, LinkAce recommends using utf8mb4_unicode_ci collation. See Adjusting the Database Collation for details.

  • API Reference - REST API endpoints for working with models
  • Advanced Settings - Environment configuration
  • User Management - Managing users and permissions