Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Duplicate Field Laravel Package

jackabox/nova-duplicate-field

A Laravel Nova field that adds a one-click duplicate action to your resources, letting admins copy records and relationships from the index or detail view. Simple to install and customize for faster CRUD workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

This package adds a replication layer on top of Laravel models so you can duplicate a record (and optionally its relations) without hand-writing replicate() + fill() boilerplate. v0.3.0 adds per-field control — you can now ignore fields (never copied) or override them (copied but replaced with a computed value) during replication.

Minimal setup:

composer require <vendor>/<package>
php artisan vendor:publish --tag=replication-config

Then replicate your first record:

use Vendor\Package\Facades\Replicator;

$copy = Replicator::make($product)
    ->ignore(['sku', 'slug'])
    ->override(['status' => 'draft', 'created_by' => auth()->id()])
    ->save();

Where to look first, in order:

  1. config/replication.php — global ignore/override defaults and the model resolver. This is where 90% of "why was this field copied?" questions get answered.
  2. The Replicator facade / service contract — the fluent API (make, ignore, override, withRelations, save).
  3. Any Replicates trait or replicationConfig() method you can add to models — per-model defaults live here, not in config.
  4. The package tests — the fastest way to see how nested relations and casted attributes are handled, which the README tends to undersell.

First real use case: "duplicate this product/listing/page as a draft". You want a new row with a fresh ID, a handful of identity fields (sku) stripped, and ownership/status reset — exactly the ignore/override split.

Implementation Patterns

Ignore vs. override — pick deliberately. ignore() removes a field entirely (the DB default or null applies). override() keeps the column in the payload but swaps the value. For anything with a NOT NULL + no-default column, use override, not ignore, or the insert fails.

Identity fields belong in ignore, ownership in override:

$copy = Replicator::make($page)
    ->ignore(['slug', 'uuid', 'published_at'])      // regenerated downstream
    ->override(['status' => 'draft', 'author_id' => auth()->id()])
    ->save();

$copy->update(['slug' => Str::slug($copy->title).'-'.Str::random(6)]);

Per-model defaults via a trait/config method so controllers stay thin:

class Product extends Model
{
    use Replicates;

    public function replicationConfig(): array
    {
        return [
            'ignore'   => ['sku', 'slug'],
            'override' => ['status' => 'draft'],
        ];
    }
}

Call-site overrides should merge on top of (not replace) model defaults — verify this in your version, since it's the most common source of surprise.

Controller + form request pattern. Validate the user-supplied overrides only, then hand them to the replicator. Don't let request input reach the override map unfiltered — that's a mass-assignment hole with a different name.

Bulk replication. Wrap in a job and chunk; the fluent builder is per-record. For "duplicate this template into 50 tenants", loop the builder inside DB::transaction() per record rather than one giant transaction.

Relations. If the package supports withRelations(), replicate children after the parent saves so you can point foreign_id at the new ID via override. Do not assume children()->replicate() cascades — it doesn't in most implementations.

Testing. Assert the negative space: assertNull($copy->sku), assertNotEquals($original->uuid, $copy->uuid), assertSame('draft', $copy->status). Snapshot-style assertions on the whole attribute array break on every schema change.

Gotchas and Tips

  • Ignoring a unique column doesn't generate a new value. You still need a slug/SKU strategy. The feature removes the copy, not the obligation.
  • ignore() on a column with no DB default throws on insert. Prefer override when in doubt; check SHOW CREATE TABLE before trusting an ignore list.
  • Timestamps and soft deletes. Confirm whether created_at/updated_at are excluded by default. If you ignore deleted_at but copy deleted_at's value implicitly, a soft-deleted original can produce a soft-deleted copy — usually not what you want.
  • Observers and model events fire on the replica. creating/created/saved hooks (audit logs, search indexing, slug generation) run against the new record. If the package's own save bypasses Eloquent, your observers won't fire — test both directions and pick one behaviour intentionally.
  • Casts and JSON columns are copied by value from the hydrated model, so array/json casts round-trip cleanly, but Carbon instances are shared objects unless cloned — mutate the copy's dates carefully.
  • $fillable/$guarded still apply if the package uses fill(). An override for a non-fillable column silently disappears. Use forceFill semantics or add the field to $fillable.
  • Config caching. php artisan config:cache in deploy means edits to config/replication.php won't take effect until re-cached. Classic "works locally, not in prod" for this class of package.
  • Debugging the resolved payload. Before save(), dump the resolved ignore/override arrays and the final attribute set. When a field "mysteriously" copies, it's almost always precedence: config default < model replicationConfig() < call-site override. Know which layer won.
  • Extension points to reach for, in order: model-level replicationConfig(), then call-site ignore/override, then a custom field resolver or macro if the package exposes one. Avoid forking the replicator for one quirky model.
  • Version pin. v0.3.0 is pre-1.0; the fluent API surface is still moving. Pin the minor version and re-read the changelog on bumps — the ignore/override precedence rules are exactly the kind of thing that shifts between 0.x releases.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle