replicate method
Clone the model into a new, non-existing instance.
Creates a copy of this model without:
- Primary key
- Timestamps (created_at, updated_at if they exist)
- Unique identifiers
The except parameter allows you to specify additional fields to exclude
from the replication.
Example:
final user = await User.query().find(1);
final duplicate = user.replicate(except: ['email']);
duplicate.setAttribute('email', 'new@example.com');
await duplicate.save();
Implementation
TModel replicate({List<String>? except}) {
final def = expectDefinition();
// Default fields to exclude
final defaultExclude = <String>{
if (def.primaryKeyField != null) def.primaryKeyField!.name,
// Exclude common timestamp fields
'created_at',
'updated_at',
'createdAt',
'updatedAt',
};
// Merge with user-provided exclusions
final excluded = except != null
? {...defaultExclude, ...except}
: defaultExclude;
// Get all current field values by serializing the model
final currentAttributes = toRecord();
// Copy current attributes and null out excluded fields
final newAttributes = Map<String, Object?>.from(currentAttributes);
for (final field in def.fields) {
if (excluded.contains(field.name) ||
excluded.contains(field.columnName)) {
// Excluded fields are set to null (codec will handle validation/defaults)
newAttributes[field.name] = null;
newAttributes[field.columnName] = null;
}
}
// Create and return new instance using codec
// Use the connection resolver's codec registry to ensure driver-specific codecs are used
final registry = connectionResolver?.codecRegistry;
final instance = def.fromMap(newAttributes, registry: registry);
// Mark as new (not yet persisted) using the Expando
_modelExists[instance] = false;
return instance;
}