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

BelongsToMany Relation #31

Open
ssmusoke opened this issue Feb 19, 2021 · 15 comments
Open

BelongsToMany Relation #31

ssmusoke opened this issue Feb 19, 2021 · 15 comments

Comments

@ssmusoke
Copy link

While the documentation is very clear that this is not in scope, I thought that it would still be great to open up a discussion here on the feature.

I coming from Nova and the way it was simplified was that the BelongsToMany is only available after a resource has been created/edited and you can only work on the pivot table relationship

IMO this would simplify the implementation

Thoughts and comments are welcome

@stancl
Copy link
Member

stancl commented Feb 19, 2021

If you want native BelongsToMany support it'd help me a lot if you could share your exact uses of the relation.

The thing about BelongsToMany is that it can represent vastly different things (and the UI for each of those things would be very unique), so I want to have an idea about what people are commonly using it for.

@ssmusoke
Copy link
Author

Here are screenshots from how I have used it before in Nova adding roles and permissions for a user - all the UI provides is adding the pivot-table relationship, possibly if additional fields are provided there may be a model to edit and create

User_Details

@stancl
Copy link
Member

stancl commented Feb 21, 2021

I see. I can think of the following use cases:

  • Order belongstomany Products (with a lot of stuff in the pivot table)
  • Tags
  • Roles/permissions
  • Team users
  • Multistore product mappings

@ssmusoke
Copy link
Author

And I see them in two major categories

  • Default Simple): no additional fields in the pivot table, just mapping of ID columns - timestamps and auto increment ids are auto generated
  • Advanced/Custom pivot table relation: Have additional data columns in the pivot table that have data that needs to be validated and checked for completeness

@robertorinaldi-dev
Copy link

A feature which could be useful sometimes is the possibility to set a limit to the number of related resources. If the limit is reached, the add button became disabled. I don't know if I'm the only one who ever needed something like this.

@stancl
Copy link
Member

stancl commented Feb 22, 2021

@roberto-mgquadro What was the use case for that? Can you give an example?

I can imagine this working with HasMany too.

@robertorinaldi-dev
Copy link

The last time I needed this feature was for creating padel teams. Each team could have a maximum of 2 players (1 in case the teammate has not yet been found). Same thing for the creation of the matches, each of which could have a maximum of two challengers.

@stancl
Copy link
Member

stancl commented Feb 22, 2021

Ah yeah that makes sense. Does Laravel let you do $this->belongsToMany(Foo::class)->limit(2)?

And if so, does it enforce it on both reads and writes or only reads? 🤔

@robertorinaldi-dev
Copy link

As far as I know, no. For this reason, a limit at a higher level may be useful

@robertorinaldi-dev
Copy link

I know that I could have created the two players directly on the team, but it was inconvenient for me due to other features. Furthermore, this example can be adapted to cases where the maximum is not only 2 but maybe 4 or 10.

@stancl
Copy link
Member

stancl commented Feb 22, 2021

That's a good suggestion. I guess I can add ->limit() and make it read from the relation by default.

@ssmusoke
Copy link
Author

Additional use cases

  • Timesheets - assign projects to a user with a start date, end date, maximum hours per week, minimum hours per week
  • Sports - add teams to a league or competition
  • LMS - add users to courses, with a start date when they can do it

@MikeCraig418
Copy link

MikeCraig418 commented Apr 29, 2021

One thing that is difficult to configure with HasMany/BelongsToMany in Nova are the pivot fields.

Any relational component here would be improved greatly if Pivot tables / custom fields on the pivot model can be accessed and edited.

@stancl
Copy link
Member

stancl commented Apr 29, 2021

@949mac Can you describe exactly what pains you had with it in Nova? I don't think I've used it.

@molcsab
Copy link

molcsab commented Oct 7, 2021

This is my use case for BelongsToMany:

Simplified table structure:

contracts
    id - integer
    contract_number - string

machines
    id - integer
    name - string

contract_machine
    id - integer
    contract_id - integer
    machine_id - integer
    serial_number - string
    manufacture_year - year

My models and resources in Nova:

// Contract Model
class Contract extends Model
{
public function machines()
    {
        return $this->belongsToMany(Machine::class)
        ->withPivot(['id','serial_number','manufacture_year']);
    }
}

// Machine Model
class Machine extends Model
{
public function contracts()
    {
        return $this->belongsToMany(Contract::class)
            ->withPivot(['serial_number','manufacture_year']);
    }
}

// Contract Resource (Nova)
class Contract extends Resource
{
    public function fields(Request $request)
    {
        return [
            ID::make('ID', 'id')->sortable(),
            BelongsToMany::make('Machines', 'machines', Machine::class)
                ->fields(function () {
                    return [
                        Text::make('Serial Number','serial_number'),
                        Text::make('Manufacture Year','manufacture_year'),
                    ];
                })
                ->allowDuplicateRelations()
                ->searchable(),
        ];
    }
}

// Machine Resource (Nova)
class Machine extends Resource
{
    public function fields(Request $request)
    {
        return [
            ID::make('ID', 'id')->sortable(),
            BelongsToMany::make('Contracts','contracts',Contract::class)
            ->fields(function () {
                return [
                    Text::make('Serial Number','serial_number'),
                    Text::make('Manufacture Year','manufacture_year'),
                ];
            }),
        ];
    }
}    

I'll have to be able to attach and dispaly exisitng machines to a contract with additional fields in the pivot table

Contract_Details

I am in the process to rewrite the application with Lean and the BelongsToMany relation would come very handy, or or some workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants