Eloquent derives a model's table and keys from its class name, and you override only what differs:
| Aspect | Convention | Laravel 13 2,157 override |
|---|---|---|
| Table | OrderItem: order_items | #[Table('name')] |
| Primary key | auto-increment id | #[Table(key: 'sku')] |
| Timestamps | created_at, updated_at | #[WithoutTimestamps] |
| Foreign key | order_item_id | relation argument |
The documentation now leads with these class attributes; the older properties ($table, $primaryKey, $keyType, $incrementing, $timestamps) still work and fill most existing code. Asking the model is the quickest check:
use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Database\Eloquent\Model;
class OrderItem extends Model {}
#[Table('order_items', timestamps: false)]
class LineItem extends Model {}
$m = new OrderItem;
echo $m->getTable(), ' ', $m->getKeyName(), ' ', $m->getForeignKey(), "\n";
echo (new LineItem)->getTable(), ' ', json_encode((new LineItem)->usesTimestamps()), "\n";Output
order_items id order_item_id order_items false
No query ran: inference is string work, so a wrong guess surfaces only at the first query. That table also shows the limit: its key is the pair (order_id, product_id), and Eloquent has no composite keys, so treat it as a pivot (Many to Many) or give it a surrogate id.