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

Connective Laravel Package

aurorawebsoftware/connective

Connective is a Laravel package for defining and managing connections between your application's entities. It offers a clean, expressive API for creating, querying, and maintaining links, helping you keep complex relationship logic organized and easy to work with.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first. This package ships with a one-line description ("This is my package connective"), zero stars and zero dependents. Before you write a single line of application code, treat the repository itself as the documentation — there is no community knowledge base to fall back on.

Install and inspect (10 minutes, do this before anything else):

composer require aurorawebsoftware/connective

Then, in order:

  1. vendor/aurorawebsoftware/connective/README.md — if it's still the Laravel skeleton readme, assume zero docs and read the source.
  2. vendor/aurorawebsoftware/connective/composer.json — check require (Laravel/PHP version constraints) and autoload. A psr-4 namespace like AuroraWebSoftware\Connective\ tells you the root class names.
  3. src/ — look for a ConnectiveServiceProvider, a facade, a Traits/ directory, and a Models/ directory. Those four files tell you 90% of the public API.
  4. database/migrations/ — the schema is the contract. Read the column names; they reveal what the package actually models (a pivot-style connection table, polymorphic morph columns, a type/group discriminator, JSON meta).
  5. config/connective.php (if present) — table name, model class overrides, morph map settings.

First use case. Because the name implies model-to-model linking, the minimal happy path is almost always:

php artisan vendor:publish --tag=connective-migrations   # confirm the tag from the provider
php artisan migrate
use AuroraWebSoftware\Connective\Traits\Connective; // verify actual name

class Post extends Model
{
    use Connective;
}

$post->connect($user);            // or Connective::connect($post, $user)
$post->connections;              // verify relation name in the trait

Verify each of those symbols against src/ before committing. If the provider registers no publishable config and no migration, the package is likely a pure trait/helper and you'll rely on your own table — check for a stubs/ folder.

Adoption gate: if you can't get from composer require to a passing php artisan tinker connect/read/disconnect in under 30 minutes using only the source, do not put it in a production dependency graph. The absence of docs is itself the signal.

Implementation Patterns

Wrap it, don't scatter it. With a single-maintainer package at zero stars, the highest-value pattern is a thin application-level adapter so the vendor API appears in exactly one place:

// app/Support/Relations/Connector.php
final class Connector
{
    public static function link(Model $from, Model $to, array $meta = []): void
    {
        // single call site for the vendor API — swap-out point if abandoned
        $from->connect($to, $meta);
    }
}

Everything else in the codebase depends on Connector, not on Connective. This costs one file and buys you a one-day migration if the package dies.

Trait-on-the-aggregate-root, not everywhere. If it exposes a trait, apply it to the models that own connections (User, Post, Project) rather than to every model. Traits that add global scopes are the usual cause of "why is my query missing rows" — check the trait body for boot{TraitName} methods before a wide rollout.

Use it for the edges of your domain, not the core. A dynamic-connection package is a good fit for tagging, follows, "related items", saved searches, feature flags per entity. It's a poor fit for anything with real business invariants (orders, payments, memberships with billing) — those deserve first-class tables with typed columns, FKs and constraints.

Typed connections over free-form metadata. If the package supports a type/group discriminator, use it and constrain it with an enum in your own code:

enum ConnectionType: string {
    case Follow   = 'follow';
    case Bookmark = 'bookmark';
}

Connector::link($user, $post, ['type' => ConnectionType::Bookmark->value]);

This keeps the connection table from becoming a junk drawer, and lets you add a partial index or a where type = ? scope later.

Eager load at the boundary. Anything polymorphic is an N+1 magnet. Load connections in the controller/action, not lazily inside Blade or an API resource:

$posts = Post::query()->with('connections')->paginate();

Transactional writes. Create the domain record and its connections inside one DB::transaction(). Connection tables are usually written after the parent, so a failed connect leaves an orphaned entity.

Seed and factory it. Add a connect() state or a small helper in your factories so RefreshDatabase tests exercise realistic graphs instead of single rows:

User::factory()->hasConnections(3)->create();

Test the contract, not the package. Write one integration test that connects two models, asserts the row exists in the DB (query the table directly, not the package's API), then disconnects. That test is your smoke alarm on composer update.

Gotchas and Tips

Treat the version constraint as untrusted. Use "aurorawebsoftware/connective": "^1.0" only after checking tags exist. If there are no tags, pin to a commit hash and commit your composer.lock. A dev-main requirement on a zero-dependent package means the next composer update can silently break you.

Migration collisions. Packages that publish migrations inherit Laravel's timestamp prefix at publish time. If the package's migration name clashes with one of yours, rename yours — never edit the vendor file.

Check for a global scope. Open the trait and look for static::addGlobalScope. A scope that filters by type or is_active will make raw DB::table() queries and reports disagree with Eloquent results. When a count looks wrong, drop to DB::table('connections')->count() to confirm.

Morph map coupling. If it uses morphs(), the stored *_type values are either FQCNs or morph aliases from Relation::enforceMorphMap(). Renaming a model class then becomes a data migration. If you use morph maps in your app, set them before writing any connections and never change them.

Missing indexes. A morphs() call gives you a composite index on (type, id), which does not serve WHERE target_type = ? AND target_id = ? lookups. Add the inverse index in your own migration if you query connections in both directions:

Schema::table('connections', fn (Blueprint $t) => $t->index(['target_type', 'target_id']));

Deletion semantics. Verify whether the package cascades on delete. Most don't, and polymorphic FKs can't cascade anyway. Add a deleting observer on connected models, or a scheduled connective:prune-style command of your own, or the table grows forever.

Debugging. When a connect silently no-ops, enable query logging and confirm the insert actually fired:

DB::listen(fn ($q) => logger($q->sql, $q->bindings));

Common causes: the trait isn't on both models, a duplicate-connection guard rejected the insert, or a type enum mismatched.

Config cache quirks. If you publish config/connective.php and override the table or model class, run php artisan config:clear — an overridden table name that's cached from a previous deploy is a classic 20-minute head-scratcher.

Extension points to look for. Before forking, check for events (ConnectionCreated, ConnectionRemoved), a repository/manager binding in the service provider, or interfaces in src/Contracts. One of those usually lets you extend behavior without touching vendor code. Also check whether the config allows swapping the connection model — that's the cheapest way to add columns.

The exit plan. Keep the adapter from the Implementation Patterns section, and write down the two SQL statements that replace the package (INSERT INTO connections ..., SELECT ... WHERE). If the package goes unmaintained, that note is the whole migration.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource