I have a laravel model based on the following table:
public function up()
{
Schema::create('things', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('label');
$table->foreignId('user_id')->nullable()->constrained('users');
});
There is also a pivot table that makes this a many-to-many self-referential model.
public function up()
{
Schema::create('thing_thing', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('message')->nullable();
$table->unsignedBigInteger('parent_id')->nullable();
$table->unsignedBigInteger('child_id')->nullable();
$table->unique(['parent_id', 'child_id']);
$table->foreign('parent_id')->references('id')->on('things')->onDelete('cascade');
$table->foreign('child_id')->references('id')->on('things')->onDelete('cascade');
});
}
When I create a Nova resource linked to this model, I would like to restrict the attaching of a thing
to itself. So a thing
with id = 1
, for example, would not show up in the selector for attachments for the thing with id = 1
. Here's my Nova resource:
public function fields(Request $request)
{
return [
ID::make(__('ID'), 'id')->sortable(),
Text::make('label'),
ID::make('user_id')->hideWhenUpdating()->hideWhenCreating(),
BelongsToMany::make('Trees', 'trees'),
BelongsToMany::make('Things', 'childOf'),
BelongsToMany::make('Things', 'parentOf')
];
}
You can solve this through the App\Nova\Ressource
's relatableQuery
method. Simply override the method in your nova resource:
class Thing extends Resource {
// ...
public static function relatableQuery(NovaRequest $request, $query)
{
// Make sure you only apply the filter to the things-things relatable query
if( $request->route('resource') === 'things' ) {
$currentId = $request->route('resourceId');
$query->where('id', '!=', $currentId);
}
return $query
}
}
You can find the docs here
In addition, you might want to make the column-combination of parent_id
and child_id
unique in your migration to further ensure uniqueness.