Skip to content

Model Relationships ​

FluentCart uses Eloquent ORM relationships to establish connections between different models. Understanding these relationships is crucial for efficient data querying and manipulation.

Relationship Types ​

FluentCart models use the following relationship types:

  • One-to-One - Each model has one related model
  • One-to-Many - One model has many related models
  • Many-to-Many - Models can have multiple related models
  • Polymorphic - Models can relate to multiple different model types

Core Model Relationships ​

Order Relationships ​

The Order model is central to FluentCart and has multiple relationships:

php
// Order belongs to one Customer
$order = Order::find(1);
$customer = $order->customer;

// Order has many Order Items
$orderItems = $order->items;

// Order has many Transactions
$transactions = $order->transactions;

// Order has many Meta entries
$meta = $order->meta;

// Order belongs to one Subscription (optional)
$subscription = $order->subscription;

Order Model Relationships ​

RelationshipTypeRelated ModelForeign KeyLocal Key
customerbelongsToCustomercustomer_idid
itemshasManyOrderItemorder_idid
transactionshasManyOrderTransactionorder_idid
metahasManyOrderMetaorder_idid
subscriptionbelongsToSubscriptionsubscription_idid

Customer Relationships ​

Customers are connected to multiple entities:

php
// Customer has many Orders
$customer = Customer::find(1);
$orders = $customer->orders;

// Customer has many Subscriptions
$subscriptions = $customer->subscriptions;

// Customer has many Activities
$activities = $customer->activities;

// Customer has many Carts
$carts = $customer->carts;

// Customer has many Licenses (Pro)
$licenses = $customer->licenses;

Customer Model Relationships ​

RelationshipTypeRelated ModelForeign KeyLocal Key
ordershasManyOrdercustomer_idid
subscriptionshasManySubscriptioncustomer_idid
activitieshasManyActivitycustomer_idid
cartshasManyCartcustomer_idid
licenseshasManyLicensecustomer_idid

Product Relationships ​

Products have complex relationships for variations and metadata:

php
// Product has many Variations
$product = Product::find(1);
$variations = $product->variations;

// Product has many Order Items
$orderItems = $product->orderItems;

// Product has many Licenses (Pro)
$licenses = $product->licenses;

// Product belongs to many Categories (WordPress)
$categories = $product->categories;

Product Model Relationships ​

RelationshipTypeRelated ModelForeign KeyLocal Key
variationshasManyProductVariationproduct_idID
orderItemshasManyOrderItempost_idID
licenseshasManyLicenseproduct_idID
categoriesbelongsToManyCategorypost_idterm_id

Subscription Relationships ​

Subscriptions connect customers to recurring orders:

php
// Subscription belongs to one Customer
$subscription = Subscription::find(1);
$customer = $subscription->customer;

// Subscription has many Orders
$orders = $subscription->orders;

// Subscription has many Transactions
$transactions = $subscription->transactions;

// Subscription has many Licenses (Pro)
$licenses = $subscription->licenses;

Subscription Model Relationships ​

RelationshipTypeRelated ModelForeign KeyLocal Key
customerbelongsToCustomercustomer_idid
ordershasManyOrdersubscription_idid
transactionshasManyOrderTransactionsubscription_idid
licenseshasManyLicensesubscription_idid

Pro Plugin Relationships ​

License Relationships (Pro) ​

Licenses have relationships with multiple entities:

php
// License belongs to one Customer
$license = License::find(1);
$customer = $license->customer;

// License belongs to one Product
$product = $license->product;

// License belongs to one Order
$order = $license->order;

// License belongs to one Subscription (optional)
$subscription = $license->subscription;

// License has many Activations
$activations = $license->activations;

// License has many Meta entries
$meta = $license->meta;

// License has many Transactions
$transactions = $license->transactions;

License Model Relationships ​

RelationshipTypeRelated ModelForeign KeyLocal Key
customerbelongsToCustomercustomer_idid
productbelongsToProductproduct_idID
orderbelongsToOrderorder_idid
subscriptionbelongsToSubscriptionsubscription_idid
activationshasManyLicenseActivationlicense_idid
metahasManyLicenseMetalicense_idid
transactionshasManyLicenseTransactionlicense_idid

Relationship Usage Examples ​

Eager Loading ​

Prevent N+1 queries by eager loading relationships:

php
// Load orders with their customers and items
$orders = Order::with(['customer', 'items', 'transactions'])->get();

// Load customers with their orders and subscriptions
$customers = Customer::with(['orders', 'subscriptions'])->get();

// Load products with their variations
$products = Product::with(['variations'])->get();

Querying with Relationships ​

Use relationships in queries:

php
// Get orders for customers with specific email
$orders = Order::whereHas('customer', function($query) {
    $query->where('email', '[email protected]');
})->get();

// Get customers who have active subscriptions
$customers = Customer::whereHas('subscriptions', function($query) {
    $query->where('status', 'active');
})->get();

// Get products that have been ordered
$products = Product::whereHas('orderItems')->get();

Filtering by Relationship Data ​

php
// Get orders with total greater than $100
$orders = Order::whereHas('items', function($query) {
    $query->where('line_total', '>', 10000);
})->get();

// Get customers with orders in specific date range
$customers = Customer::whereHas('orders', function($query) {
    $query->whereBetween('created_at', ['2024-01-01', '2024-01-31']);
})->get();

Counting Relationships ​

php
// Get customers with order count
$customers = Customer::withCount('orders')->get();

// Get products with order item count
$products = Product::withCount('orderItems')->get();

// Get orders with item count
$orders = Order::withCount('items')->get();

Complex Relationship Queries ​

php
// Get customers with their latest order
$customers = Customer::with(['orders' => function($query) {
    $query->latest()->limit(1);
}])->get();

// Get orders with their customer's subscription status
$orders = Order::with(['customer.subscriptions' => function($query) {
    $query->where('status', 'active');
}])->get();

// Get products with their most recent order
$products = Product::with(['orderItems.order' => function($query) {
    $query->latest()->limit(1);
}])->get();

Relationship Best Practices ​

1. Use Eager Loading ​

Always eager load relationships to prevent N+1 queries:

php
// Bad - N+1 queries
$orders = Order::all();
foreach ($orders as $order) {
    echo $order->customer->name; // N+1 query
}

// Good - Eager loading
$orders = Order::with('customer')->get();
foreach ($orders as $order) {
    echo $order->customer->name; // No additional queries
}

2. Use Specific Columns ​

Only load the columns you need:

php
// Load only specific columns
$orders = Order::with(['customer:id,name,email'])->get();

3. Use Constraints ​

Apply constraints to relationships:

php
// Load only active subscriptions
$customers = Customer::with(['subscriptions' => function($query) {
    $query->where('status', 'active');
}])->get();

4. Use Lazy Loading Wisely ​

Lazy load when you don't always need the relationship:

php
$order = Order::find(1);

// Only load when needed
if ($needCustomer) {
    $customer = $order->customer;
}

5. Use Relationship Methods ​

Use relationship methods for complex queries:

php
// Get orders for specific customer
$customer = Customer::find(1);
$orders = $customer->orders()->where('status', 'completed')->get();

// Get active subscriptions for customer
$activeSubscriptions = $customer->subscriptions()->active()->get();

Common Relationship Patterns ​

1. Parent-Child Relationships ​

php
// Order -> Order Items
$order = Order::find(1);
$items = $order->items;

// Customer -> Orders
$customer = Customer::find(1);
$orders = $customer->orders;

2. Many-to-Many Relationships ​

php
// Product -> Categories
$product = Product::find(1);
$categories = $product->categories;

// Customer -> Products (through orders)
$customer = Customer::find(1);
$products = $customer->orders()->with('items.product')->get();

3. Polymorphic Relationships ​

php
// Activities can belong to different models
$activities = Activity::where('object_type', 'order')
    ->where('object_id', 1)
    ->get();

Performance Considerations ​

1. Index Foreign Keys ​

Ensure foreign key columns are indexed:

sql
-- Add indexes for better performance
ALTER TABLE fct_orders ADD INDEX idx_customer_id (customer_id);
ALTER TABLE fct_order_items ADD INDEX idx_order_id (order_id);
ALTER TABLE fct_subscriptions ADD INDEX idx_customer_id (customer_id);

2. Use Query Scopes ​

Create scopes for common relationship queries:

php
// In Order model
public function scopeWithCustomer($query) {
    return $query->with('customer');
}

public function scopeWithItems($query) {
    return $query->with('items');
}

// Usage
$orders = Order::withCustomer()->withItems()->get();

3. Cache Relationship Data ​

Cache frequently accessed relationship data:

php
// Cache customer orders
$customer = Customer::find(1);
$orders = Cache::remember("customer_{$customer->id}_orders", 3600, function() use ($customer) {
    return $customer->orders()->with('items')->get();
});

FluentCart developer documentation