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