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
[Request] Custom Pivot Models #2093
Comments
What would you suggest as syntax for that ? How would you set which model to use ? |
Looking at it my original idea it probably wouldn't work as the custom collection just over rides the Eloquent method to create a collection. You could add another two method to BelongsToMany a setPivotModel and getPivotModel and resolve it in the same way you pass a string as the relationships related model. I haven't studied the code too closely to have an exact answer. |
I have a bit of a need for this as well (extra fields on the pivot relationship with custom getters/setters, i.e. who created it), but I've been working around it using hasMany and belongsTo:
This works, but I'd prefer to access fields as members of the pivot property. Syntactically, could this could be an extra parameter to hasMany/belongsToMany?
I'm not going to pretend I know how this would be implemented however :) |
This would also allow for query scopes to be usable with many-many relations. |
Basically BelongsToMany.php newPivot method would be modified to call $this->related->newPivot() to get the pivot instance. |
That sounds like the best way of achieving it, thanks Taylor. Will this feature get added or does this request need to become an issue / have some code written for it? |
Done. |
Can you give an example on how to use this? I don't get where you specify which model should be used for the pivot. |
For ref (this doesn't appear to be in docs yet) - this was implemented in 45d7582. Say you have a User and a Group, and a User can be in many Groups. Implemented as so:
To add an intermediate/pivot model UserGroup, implement the newPivot method on User and Client. This is called when you try to access the pivot table of a model (i.e.
This is called when you use
|
Just wanted to update this issue in case someone comes across the instructions in the previous comment and didn't notice the "Defining A Custom Pivot Model" section in the docs. The code in the previous comment might not work for you. This code might: use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Eloquent\Relations\Pivot;
class User extends Eloquent {
public function groups() {
return $this->belongsToMany('Group');
}
public function newPivot(Eloquent $parent, array $attributes, $table, $exists) {
if ($parent instanceof Group) {
return new UserGroup($parent, $attributes, $table, $exists);
}
return parent::newPivot($parent, $attributes, $table, $exists);
}
}
class Group extends Eloquent {
public function users() {
return $this->belongsToMany('User');
}
public function newPivot(Eloquent $parent, array $attributes, $table, $exists) {
if ($parent instanceof User) {
return new UserGroup($parent, $attributes, $table, $exists);
}
return parent::newPivot($parent, $attributes, $table, $exists);
}
}
class UserGroup extends Pivot {
public function user() {
return $this->belongsTo('User');
}
public function group() {
return $this->belongsTo('Group');
}
// Note: Adding relationships to a pivot model means
// you'll probably want a primary key on the pivot table.
public function posts($value) {
return $this->hasMany('Post'); // example relationship on a pivot model
}
} Note the differences:
Also, adding |
@joshuajabbour - Just came across your post while looking how to create a custom pivot. In your example above, how would you save to the pivot table? I've tried the usual $user->pivot->save() with some data but that did not work. |
@rbruhn Using a custom pivot model doesn't change how you interact with them. Whether you're using the default $user->pivot_relationship()->attach(1, array('custom_pivot_field' => 'abc'));
// or
$user->pivot_relationship()->sync(array(1 => array('custom_pivot_field' => 'abc'))); |
Thanks!! |
First, thanks for your post! I'm facing a problem with this I cannot solve. My custom Model works. I have a Game model, a Team model and a custom GameTeam model for the pivot table. Now I have an additional Bet model which has a belongsToMany relationship to the GameTeam model and the custom GameTeam model should also have a belongsToMany relationship to the Bet model. So there is another pivot table between GameTeam and Bet. This seems to be similar to the posts-method of your code. Could anyone provide me the code of the Post model here? I always get the following error if I want to call $bet->gameTeams Error: Here is my code: Game Model class Game extends Eloquent {
} Team model class Team extends Eloquent {
} GameTeam custom pivot model class GameTeam extends Pivot {
} Bet model class Bet extends Eloquent {
} |
Very nice tut @joshuajabbour ! I'm using it for some weeks/months now and it works like a charm. One question though; is it possible to hook into a attach/detach/save/delete function on the Custom Pivot Model? I would very much like to have/define Model Events for Pivot Models in the same way as Eloquent Models have; e.g. |
I also have exactly same scenario like @peiphb02 . And exact same error. Can anyone help. Could find find solution yet. |
@hhsadiq |
@peiphb02 |
@joshuajabbour I have similar problem and I am not able to user pivot table model (pivot) like a model. I want to use posts method you have described, but I cannot get what is the value parameter for and how to use it? I tried eager loading and normal but I get errors all the time. @peiphb02 I tried to create model instead of pivot, but not sure what I am doing wrong still cannot get the result, could you please share code sample. thank you in advance |
@joshuajabbour Hi, from your custom pivot model example above, is it possible to do the inverse relationship on Post? As I tried to do so, but the following error occurred:
|
@peiphb02 @joshuajabbour |
I've had the issue where I can't instantiate the pivot model. If I could do a normal attach and somehow return the instance of the pivot model that was created, that would be great. I can't figure out for the life of me how to create the pivot row then reliably get the row that was created. |
For those who still having trouble with this, i'm confused too but i did it work with the help on https://softonsofa.com/laravel-custom-pivot-model-in-eloquent/ |
The above solution from @joshuajabbour worked for me when using a many-to-many relation, however it doesn't work with polymorphic many-to-many relation. The situation I have is, I need to attach media to multiple models like pages, posts etc, and when I attach the media to a page, then I can add caption to each image, but I need this to be in multiple language, so I need more than one captions (one for each language) to the relation of image & page/post. any Idea how should I got about this ? |
I ended up convert my Polymorphic many-to-many relationship to a normal many-to-many relationship with where clause on type field, e.g
And then I used the solution proposed by @joshuajabbour . So now when I attach the media to Page, I use
|
Same for me. I had to change from Polymorphic many-to-many relationship to normal many-to-many relationship. Would be nice if this could be a little bit nicer. |
Take a look at: https://stackoverflow.com/a/44932979/2723301 Tested on Laravel 5.4 |
@rhulshof take a look at this package if you want to catch those events https://github.com/fico7489/laravel-pivot |
It would be nice if it was possible to set a custom Pivot table model for use by the BelongsToMany relationship.
Currently the 'new Pivot()' call is hard coded, I propose / request a similar solution to the custom collection that currently exists, i.e set a custom model class name if desired. If not set the pivot class is returned as it is now.
The concept allows you to utilise more data from the pivot table in a cleaner way, i.e. using getters and setters and generally having more control over the data you are trying to use.
Everything else can stay the same and the required fields can still be defined in the creation of the relationship.
Simon
The text was updated successfully, but these errors were encountered: