Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Double entries with relationships #37

Open
RibesAlexandre opened this issue Sep 28, 2024 · 2 comments
Open

[Bug]: Double entries with relationships #37

RibesAlexandre opened this issue Sep 28, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@RibesAlexandre
Copy link
Contributor

What happened?

Hi,

I've 3 entries in my navigation_items database, a hasMany relationship to Navigation Model like this :

Navigation Model Table :

Capture d’écran 2024-09-28 à 17 00 48

NavigationItem Model Table :

Capture d’écran 2024-09-28 à 17 04 59

My Navigation Model is like this :

class Navigation extends Model
{
    use \Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;

    protected $fillable = [
        'name' ,
        'slug' ,
        'position' ,
        //'items'
    ];

    public function items(): HasMany
    {
        return $this->hasMany(NavigationItem::class, 'navigation_id')
            ->whereNull('parent_id')
            ->with('childrenAndSelf')
            ->orderBy('sort');
    }

And this is my NavigationItemModel :

class NavigationItem extends Model
{
    use \Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;

    protected $fillable = ['navigation_id', 'parent_id', 'label', 'sort', 'data'];

    public $timestamps = false;

    protected $casts = [
        'data' => 'array'
    ];

    public function children(): HasMany
    {
        return $this->hasMany(NavigationItem::class, 'parent_id')
            ->with('children')
            ->orderBy('sort');
    }

My AdjencyList is like this :

AdjacencyList::make('items')
                            ->label(__('filament-starter::translations.labels.items'))
                            ->visible(fn($record) => $record !== null)
                            ->relationship('items')
                            //->childrenKey('children')
                            ->maxDepth(config('filament-starter.navigation.settings.max_depth', 6))
                            ->form([ // etc...

When I comment ->whereNull('parent_id') from my Navigation Model, items appears twice, like this :

Capture d’écran 2024-09-28 à 17 03 38

But when I keep it, only parents appears :

Capture d’écran 2024-09-28 à 17 04 21

I don't understand if it's a bug or If I do a mistake. I followed the documentation and got this. Any explications ?

Thanks you

How to reproduce the bug

Just create 2 models related with tables :

Navigation

        Schema::create('navigations' , function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('slug')->unique();
            $table->string('position');
            $table->timestamps();
        });
}

// NavigationModel 

    use \Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;

    protected $fillable = [
        'name' ,
        'slug' ,
        'position' ,
        //'items'
    ];

    public function items(): HasMany
    {
        return $this->hasMany(NavigationItem::class, 'navigation_id')
            ->whereNull('parent_id')
            ->with('childrenAndSelf')
            ->orderBy('sort');
    }

NavigationItem :

Schema::create('navigation_items' , function (Blueprint $table) {
            $table->id();
            $table->string('label');
            $table->foreignId('navigation_id')->constrained()->references('id')->on('navigations')->cascadeOnDelete();
            $table->foreignId('parent_id')->constrained()->references('id')->on('navigation_items')->cascadeOnDelete();
            $table->json('data');
            $table->string('sort');
        });

// NavigationItemModel 
    use \Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;

    protected $fillable = ['navigation_id', 'parent_id', 'label', 'sort', 'data'];

    public $timestamps = false;

    protected $casts = [
        'data' => 'array'
    ];

    public function children(): HasMany
    {
        return $this->hasMany(NavigationItem::class, 'parent_id')
            ->with('children')
            ->orderBy('sort');
    }

And NavigationResource :

AdjacencyList::make('items')
                        ->label(__('filament-starter::translations.labels.items'))
                        ->visible(fn($record) => $record !== null)
                        ->relationship('items')
                        //->childrenKey('children')
                        ->maxDepth(config('filament-starter.navigation.settings.max_depth', 6))
                        ->form([
                            Forms\Components\TextInput::make('label')
                                ->label('Label')
                                ->required(),
                               ->options(['external_link' => 'External Link']),

                            Forms\Components\Group::make()
                                ->statePath('data')
                                ->whenTruthy('type')
                                ->live()
                                ->schema([
                                    Forms\Components\TextInput::make('url')
                                        ->label(__('filament-starter::translations.labels.url'))
                                        ->required(),
                                    Forms\Components\Select::make('target')
                                        ->label(__('filament-starter::translations.navigation.select-options.target'))
                                        ->options([
                                            '' => __('filament-starter::translations.navigation.select-options.same-tab'),
                                            '_blank' => __('filament-starter::translations.navigation.select-options.new-tab'),
                                        ])
                                        ->live()
                                        ->default(''),
                                ]),

Package Version

2.2.1

PHP Version

8.2.0

Laravel Version

^11

Which operating systems does with happen with?

macOS

Notes

No response

@RibesAlexandre RibesAlexandre added the bug Something isn't working label Sep 28, 2024
@maisur
Copy link

maisur commented Oct 17, 2024

i got the same bug too

@chickgit
Copy link

I encountered the same issue, and after investigating, it seems the root cause is related to how the nested tree is retrieved.

In staudenmeir/laravel-adjacency-list, the correct way to get a nested tree structure is by using:
Model::tree()->get()->toTree();
However, in this package, the method being used is:
Model::get()->toTree();

This causes the nested tree to return duplicated data, which is unintended.

After looking into the issue further, I found a helpful suggestion from the author in this GitHub issue discussion.

To fix this, you can modify your relationship method like this:

->relationship('items', fn($query, $record) => 
    $query->getRelation('children')
          ->getRelated()::treeOf(fn($queryTree) => 
              $queryTree->isRoot()->where('navigation_id', $record->id)
          )
)

Additionally, I can confirm that this solution works in v4.0.0-beta1. I recommend considering this version, as it is backward compatible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants