Skip to content

Commit 86e9a2c

Browse files
Merge pull request #1 from OoBook/dev
feat: add new configuration structur, clear logic, and robust flow on snapshott
2 parents 1b23a51 + 32c3438 commit 86e9a2c

File tree

14 files changed

+1501
-576
lines changed

14 files changed

+1501
-576
lines changed

README.md

Lines changed: 110 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,16 @@ php artisan vendor:publish --tag="snapshot-config"
2525

2626
## Usage
2727

28+
The `HasSnapshot` trait allows you to create point-in-time copies (snapshots) of your Eloquent models while maintaining relationships. It provides both snapshot and sync capabilities for attributes and relationships.
29+
30+
### Basic Setup
31+
2832
```php
2933
<?php
3034

3135
namespace App\Models;
3236

33-
use Oobook\Snapshot\Traits\HasSnapshot;
37+
use Oobook\Snapshot\Concerns\HasSnapshot;
3438

3539
class MyProduct extends Model
3640
{
@@ -39,31 +43,120 @@ class MyProduct extends Model
3943
/**
4044
* The source model for the snapshot.
4145
*
42-
* Required
43-
*
44-
* @var Model
45-
*/
46-
public $snapshotSourceModel = YourModel::class;
47-
48-
/**
49-
* Fillable attributes to be copied from the source model.
50-
*
51-
* Optional
46+
* Required - Specifies which model to snapshot from
5247
*
53-
* @var array
48+
* @var string
5449
*/
55-
public $snapshotSourceFillable = [];
50+
public static $snapshotSourceModel = YourModel::class;
5651

5752
/**
58-
* Relationships to add to snapshot data.
59-
*
60-
* Optional
53+
* The configuration for the snapshot behavior.
6154
*
6255
* @var array
6356
*/
64-
public $snapshotSourceRelationships = [];
57+
public static $snapshotConfig = [
58+
// Attributes to take a point-in-time copy of
59+
'snapshot_attributes' => [
60+
'email'
61+
],
62+
63+
// Attributes to keep in sync with the source model
64+
'synced_attributes' => [
65+
'name',
66+
'user_type_id',
67+
],
68+
69+
// Relationships to take a point-in-time copy of
70+
'snapshot_relationships' => [
71+
'posts'
72+
],
73+
74+
// Relationships to keep in sync with the source model
75+
'synced_relationships' => [
76+
'userType',
77+
'fileNames'
78+
],
79+
];
6580
}
6681
```
82+
83+
### Configuration Options
84+
85+
#### Snapshot vs Sync
86+
87+
The trait provides two ways to handle attributes and relationships:
88+
89+
1. **Snapshot Mode** (`snapshot_attributes`, `snapshot_relationships`)
90+
- Creates a point-in-time copy of the data
91+
- Values remain unchanged even if the source model is updated
92+
- Useful for historical records or audit trails
93+
94+
2. **Sync Mode** (`synced_attributes`, `synced_relationships`)
95+
- Maintains a live connection to the source model
96+
- Values automatically update when the source model changes
97+
- Useful for maintaining current references
98+
99+
### Available Relationships
100+
101+
The snapshot model automatically provides these relationships:
102+
103+
```php
104+
// Get the snapshot data
105+
$model->snapshot;
106+
107+
// Access the original source model
108+
$model->source;
109+
110+
// Alternative way to access source model
111+
$model->snapshotSource;
112+
```
113+
114+
### Example Usage
115+
116+
```php
117+
// Create a new snapshot
118+
$snapshot = MyProduct::create([
119+
'source_id' => $sourceModel->id,
120+
'name' => 'Custom Name',
121+
'posts' => [1, 2, 3] // IDs of posts to snapshot
122+
]);
123+
124+
// Access snapshotted data
125+
echo $snapshot->email; // Shows snapshotted email
126+
echo $snapshot->name; // Shows synced name from source
127+
128+
// Access relationships
129+
$snapshot->posts; // Shows snapshotted posts
130+
$snapshot->userType; // Shows synced userType from source
131+
132+
// Update source model
133+
$sourceModel->update(['name' => 'New Name']);
134+
echo $snapshot->name; // Shows 'New Name' (synced attribute)
135+
echo $snapshot->email; // Still shows original email (snapshotted attribute)
136+
```
137+
138+
### Key Features
139+
140+
- **Automatic Syncing**: Synced attributes and relationships automatically update when the source model changes
141+
- **Relationship Handling**: Supports both HasOne/HasMany and BelongsTo/BelongsToMany relationships
142+
- **Flexible Configuration**: Choose which attributes and relationships to snapshot or sync
143+
- **Data Integrity**: Maintains separate copies of snapshotted data while keeping synced data up-to-date
144+
145+
### Important Notes
146+
147+
1. The source model must be specified using `$snapshotSourceModel`
148+
2. Configuration is optional - by default, all attributes and relationships will be snapshotted (relationships if only you use ManageEloquent Trait on source model)
149+
3. Synced relationships maintain live connections and may impact performance with large datasets
150+
4. Snapshotted relationships store a copy of the data at creation time
151+
5. `Oobook\Database\Eloquent\Concerns\ManageEloquent` Trait is offered to be used on all related models to snapshot mode
152+
153+
### Best Practices
154+
155+
- Use snapshots for historical records or audit trails
156+
- Use synced attributes for frequently changing data that should stay current
157+
- Consider performance implications when syncing large relationships
158+
- Use relationship IDs instead of full objects when creating snapshots for better performance
159+
67160
### Testing
68161

69162
```bash

src/Concerns/ConfigureSnapshot.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace Oobook\Snapshot\Concerns;
4+
5+
trait ConfigureSnapshot
6+
{
7+
8+
/**
9+
* Configuration for snapshot behavior
10+
*/
11+
protected static array $defaultSnapshotConfig = [
12+
// Fields to snapshot (point-in-time copy)
13+
'snapshot_attributes' => null,
14+
15+
// Attributes to keep in sync
16+
'synced_attributes' => null,
17+
18+
// Relationships to snapshot (point-in-time copy)
19+
'snapshot_relationships' => null,
20+
21+
// Relationships to keep in sync
22+
'synced_relationships' => null,
23+
];
24+
25+
/**
26+
* Get the snapshot configuration.
27+
*
28+
* @return array
29+
*/
30+
final public static function getSnapshotConfig(): array
31+
{
32+
return array_merge(
33+
static::$defaultSnapshotConfig,
34+
static::$snapshotConfig ?? []
35+
);
36+
}
37+
38+
public static function hasSourceAttributeToSync(): bool
39+
{
40+
$snapshotConfig = static::getSnapshotConfig();
41+
42+
return $snapshotConfig['synced_attributes'] ? count($snapshotConfig['synced_attributes']) > 0 : false;
43+
}
44+
45+
public static function getSourceAttributesToSync(): array
46+
{
47+
$snapshotConfig = static::getSnapshotConfig();
48+
49+
return $snapshotConfig['synced_attributes'] ?? [];
50+
}
51+
52+
public static function hasSourceRelationshipToSync(): bool
53+
{
54+
$snapshotConfig = static::getSnapshotConfig();
55+
56+
return $snapshotConfig['synced_relationships'] ? count($snapshotConfig['synced_relationships']) > 0 : false;
57+
}
58+
59+
public static function getSourceRelationshipsToSync(): array
60+
{
61+
$snapshotConfig = static::getSnapshotConfig();
62+
63+
return $snapshotConfig['synced_relationships'] ?? [];
64+
}
65+
}

0 commit comments

Comments
 (0)