anomaly/relationship-field_type
Anomaly Relationship Field Type provides a Laravel/Streams form field for selecting and linking related entries across streams. It adds relationship input handling to Anomaly control panels, making it easy to connect records through a simple field.
This is not a general-purpose Laravel package — it's a Streams Platform field type addon (PyroCMS / anomaly/streams-platform ecosystem). You "leverage" it by treating relationship as a built-in field type when modelling streams and modules, not by calling its classes directly.
Minimal steps:
composer require anomaly/relationship-field_typecomposer dump-autoload and, if the platform doesn't auto-scan, register the addon in your addons config / refresh the addon registry from the admin (Addons → Field Types). The addon exposes Anomaly\RelationshipFieldType\RelationshipFieldTypeServiceProvider and a RelationshipFieldType.src/RelationshipFieldType.php — the field type class (config keys, getOptions(), getInputView()).resources/views/ — the admin input (Twig in older Pyro, Blade in newer Streams).resources/config/ / config/ — defaults, typically the related target.resources/lang/ — labels, validation, warning messages.related to the target stream slug (e.g. users, blog_categories, namespace.stream). The field renders as a select/dropdown of that stream's entries.Expect this to sit alongside anomaly/text-field_type, anomaly/select-field_type, etc. — same lifecycle, same conventions.
Declaring the field in a module migration / stream definition. Use the field type slug (relationship) and pass the target stream via config:
$fields = $stream->fields();
$fields->addField('author', 'relationship', [
'config' => [
'related' => 'users', // namespace.stream or plain stream slug
],
]);
Storing vs. resolving the value. The field persists the related entry's ID. Depending on version/config, exposing it often means either reading the raw $entry->author_id-style attribute or letting the platform resolve the relation. Confirm in src/RelationshipFieldType.php whether it exposes a getRelation() / BelongsTo, and access $entry->author (related Entry) versus $entry->author_id accordingly.
Rendering the input. The field type owns the admin UI. If you need a different control (searchable select, radio list, multi-select), copy/extend the view in the addon rather than overriding in your module — the input view is the contract between the field type and the admin form.
Programmatic option building. getOptions() (or the equivalent method in the class) is where the dropdown list is produced. Use this as your extension point when the list must be filtered (e.g. only published entries, only entries in a given locale). Override via a custom field type inheriting from RelationshipFieldType rather than editing vendor code.
Front-end display. Because the stored value is an ID, display requires resolving the entry: use the Streams entry repository with find($id), or eager-load the relation when listing many entries. Cache resolved titles if you render lists frequently.
Validation. Relationship fields are effectively required-by-null by default. Add required at the field level and a exists:... style rule at the module level if you must guarantee the referenced entry still exists.
composer.json for the anomaly/streams-platform constraint before assuming compatibility with a given PyroCMS/Laravel version. 0 dependents and 1 star mean you should treat it as core-vendored code, not a community package.related config points at streams, not Eloquent models. A wrong slug silently yields an empty dropdown. Verify the stream exists and is seeded; look for the warning message in resources/lang.getOptions() with a query limit, or swap to a search/autocomplete field type.input.twig); newer Streams may use Blade. When overriding, match the engine of the platform version you're on — mixing them silently fails.php artisan addon:reload (or the admin equivalent) and clear caches; a stale registry is a common reason the type doesn't appear in the field picker.null; guard your templates and eager loads (with('author') on a null relation is a common source of errors in list views).RelationshipFieldType, register it as an addon, and reference that in migrations. Editing the vendor package is a maintenance trap — you're at the mercy of upstream Streams Platform changes.config is actually persisted on the assignment (streams_stream_fields / stream_fields table) and not just passed at migration time and lost.How can I help you explore Laravel packages today?