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
Link
The Link model represents a bookmarked URL with metadata and status tracking.
Database Table: links
Properties:
id(int) - Primary keyuser_id(int) - Foreign key to Userurl(string) - The bookmarked URLtitle(string) - Link titledescription(string|null) - Optional descriptionicon(string|null) - Icon identifiervisibility(int) - 1=Private, 2=Internal, 3=Publicstatus(int) - 1=OK, 2=Moved, 3=Brokencheck_disabled(boolean) - Whether link checking is disabledlast_checked_at(datetime|null) - Last check timestampthumbnail(string|null) - Thumbnail URLcreated_at(datetime) - Creation timestampupdated_at(datetime) - Last update timestampdeleted_at(datetime|null) - Soft delete timestamp
Relationships:
user()- BelongsTo User (with trashed)lists()- BelongsToMany LinkList (vialink_listspivot table)tags()- BelongsToMany Tag (vialink_tagspivot table)notes()- HasMany Noteaudits()- MorphMany (audit trail)
Status Constants:
Link::STATUS_OK = 1; // Link is accessible
Link::STATUS_MOVED = 2; // Link redirects
Link::STATUS_BROKEN = 3; // Link is inaccessibleDisplay Constants:
Link::DISPLAY_CARDS = 1; // Card view
Link::DISPLAY_LIST_SIMPLE = 2; // Simple list view
Link::DISPLAY_LIST_DETAILED = 3; // Detailed list viewKey Methods:
getFormattedDescriptionAttribute()- Returns markdown-formatted descriptionshortUrl()- Returns URL without https:// prefixshortTitle(int $maxLength = 50)- Returns truncated titledomainOfURL()- Extracts domain from URLgetIcon(string $additionalClasses = '')- Returns icon HTMLaddedAt()- Returns formatted creation date HTMLinitiateInternetArchiveBackup()- Dispatches Wayback Machine backup jobsearchDuplicateUrls()- Finds potential duplicate URLs
Scopes:
byUser(int $user_id = null)- Filter by userprivateOnly()- Only private linksinternalOnly()- Only internal linkspublicOnly()- Only public links
Allowed Order By Fields:
id, url, title, description, visibility, status, check_disabled, created_at, updated_at, random
LinkList
The LinkList model represents a collection of links organized by the user.
Database Table: lists
Properties:
id(int) - Primary keyuser_id(int) - Foreign key to Username(string) - List namedescription(string|null) - Optional descriptionvisibility(int) - 1=Private, 2=Internal, 3=Publiccreated_at(datetime) - Creation timestampupdated_at(datetime) - Last update timestampdeleted_at(datetime|null) - Soft delete timestamp
Relationships:
user()- BelongsTo User (with trashed)links()- BelongsToMany Link (vialink_listspivot table)
Key Methods:
getFormattedDescriptionAttribute()- Returns markdown-formatted description
Scopes:
byUser(int $user_id = null)- Filter by userprivateOnly()- Only private listsinternalOnly()- Only internal listspublicOnly()- 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 keyuser_id(int) - Foreign key to Username(string) - Tag namevisibility(int) - 1=Private, 2=Internal, 3=Publiccreated_at(datetime) - Creation timestampupdated_at(datetime) - Last update timestampdeleted_at(datetime|null) - Soft delete timestamp
Relationships:
user()- BelongsTo User (with trashed)links()- BelongsToMany Link (vialink_tagspivot table)
Scopes:
byUser(int $user_id = null)- Filter by userprivateOnly()- Only private tagsinternalOnly()- Only internal tagspublicOnly()- 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 keylink_id(int) - Foreign key to Linkuser_id(int) - Foreign key to Usernote(text) - Note contentvisibility(int) - 1=Private, 2=Internal, 3=Publiccreated_at(datetime) - Creation timestampupdated_at(datetime) - Last update timestamp
Relationships:
link()- BelongsTo Linkuser()- BelongsTo User (with trashed)
User
The User model represents a LinkAce user account.
Database Table: users
Properties:
id(int) - Primary keyname(string) - User’s display nameemail(string) - Email address (unique)email_verified_at(datetime|null) - Email verification timestamppassword(string) - Hashed passwordremember_token(string|null) - Remember me tokencreated_at(datetime) - Creation timestampupdated_at(datetime) - Last update timestampdeleted_at(datetime|null) - Soft delete timestamp
Relationships:
links()- HasMany Linklists()- HasMany LinkListtags()- HasMany Tagnotes()- HasMany Notetokens()- HasMany API tokens (Sanctum)
UserInvitation
The UserInvitation model represents an invitation to join LinkAce.
Database Table: user_invitations
Properties:
id(int) - Primary keyemail(string) - Invitee email addresstoken(string) - Invitation token (unique)created_by(int) - User ID who created the invitationused_at(datetime|null) - When invitation was usedcreated_at(datetime) - Creation timestampupdated_at(datetime) - Last update timestamp
Visibility System
All content models (Link, LinkList, Tag, Note) support a three-tier visibility system:
Visibility Levels
- Private (1) - Only visible to the owner
- Internal (2) - Visible to all authenticated users in the instance
- Public (3) - Visible to everyone, including unauthenticated guests
Implementation
Visibility is implemented through:
- The
ModelAttribute::VISIBILITY_*enum constants - The
ScopesVisibilitytrait providing query scopes:privateOnly()- Filter to private items onlyinternalOnly()- Filter to internal items onlypublicOnly()- 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_attimestamp - 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
Auditableinterface - Changes are logged to the
auditstable - Audit modifiers transform field values for readability:
VisibilityModifier- Converts visibility integers to labelsBooleanModifier- Converts booleans to Yes/NoLinkStatusModifier- Converts status integers to labelsTagRelationModifier- Tracks tag relationship changesListRelationModifier- Tracks list relationship changes
Pivot Tables
link_lists
Joins links and lists in a many-to-many relationship.
Columns:
link_id(int) - Foreign key to linkslist_id(int) - Foreign key to lists
link_tags
Joins links and tags in a many-to-many relationship.
Columns:
link_id(int) - Foreign key to linkstag_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.
Related Documentation
- API Reference - REST API endpoints for working with models
- Advanced Settings - Environment configuration
- User Management - Managing users and permissions