How to save entries in many to many polymorphic relationship in Laravel?
You can use all of the belongsToMany
methods for this, for polymorphic many-to-many extends that relation:
// I would call that relation on tag in plural 'entities()' to be more accurate
$tag->entities()->save(new or existing model, array of pivot data, touch parent = true) (used on existing model)
$tag->entities()->saveMany(array of new or existing models, array of arrays with pivot data)
$tag->entities()->attach(existing model / id, array of pivot data, touch parent = true)
$tag->entities()->sync(array of ids, detach = true)
$tag->entities()->updateExistingPivot(pivot id, array of pivot data, touch)
All of those methods work both ways of course.
Examples:
$tag = Tag::first();
$entity = Entity::find(10);
// save() works with both newly created and existing models:
$tag->entities()->save(new Entity(...));
$tag->entities()->save($entity);
// saveMany() like above works with new and/or existing models:
$tag->entities()->saveMany([$entity, new Entity(...)]);
// attach() works with existing model or its id:
$tag->entities()->attach($entity);
$tag->entities()->attach($entity->id);
// sync() works with existing models' ids:
$tag->entities()->sync([1,5,10]); // detaches all previous relations
$tag->entities()->sync([1,5,10], false); // does not detach previous relations, attaches new ones skipping existing ids
Your case:
Route::put('org/{org}', function(Org $org){
$org->description = Input::get('description');
$org->website = Input::get('website');
$org->save();
$org->tags()->sync(Input::get('tags'));
// or if you don't want to detach previous tags:
// $org->tags()->sync(Input::get('tags'), false);
return Redirect::to('org/'.$org->id)
->with('message', 'Seccessfully updated page!');
});
Related videos on Youtube
chipit24
Updated on July 19, 2020Comments
-
chipit24 almost 4 years
I have an Org model and a Tag model. I want to associate tags with organizations. My database tables and Eloquent models are set up like so ...
org id - integer name - string ... tags id - integer name - string taggables id - integer taggable_id - integer taggable_type - string // app/models/Org.php class Org extends Eloquent { protected $table = "org"; ... public function tags() { return $this->morphToMany('Tag', 'taggable'); } } // app/models/Tag.php class Tag extends Eloquent { protected $table = "tags"; public $timestamps = false; public function org() { return $this->morphedByMany('Org', 'taggable'); } }
In my view, I have a form with a multiple select box where the user can select the tags he/she wants to be associated with the organization ...
... {{ Form::select('tags[]', $tag_options, null, array( 'multiple', 'data-placeholder' => 'Select some tags')) }} ...
... And $tag_options comes from my routes.php file ...
View::composer('*', function($view) { $tags = Tag::all(); if(count($tags) > 0) { $tag_options = array_combine($tags->lists('id'), $tags->lists('name')); } else { $tag_options = array(null, 'Unspecified'); } $view->with('tag_options', $tag_options); });
When the form in my view is submitted, the following route will catch it to update the org model ...
Route::put('org/{org}', function(Org $org){ $org->description = Input::get('description'); $org->website = Input::get('website'); $org->tags = Input::get('tags'); $org->save(); return Redirect::to('org/'.$org->id) ->with('message', 'Seccessfully updated page!'); });
Now, Input::get('tags') is just an array of the tag IDs, of the form
["1","6","8"]
How can I use this to associate the tags with the organization?
I also have comments set up for organizations using a polymorphic relationship where I just do this ...
Route::put('org/post/{org}', function(Org $org){ $comment = new Comment; $comment->user_id = Auth::user()->id; $comment->body = Input::get('body'); $comment->commentable_id = $org->id; $comment->commentable_type = 'Org'; $comment->save(); return Redirect::to('org/'.$org->id) ->with('message', 'Seccessfully posted comment!'); });
However, it's not as simple with a many-to-many polymorphic relationship when I want to associate one or more tags with an organization.
Any help is appreciated, thanks!!
-
chipit24 almost 10 yearsThis doesn't really help me. Can you give an example of how I can use this for my situation? I have updated my question so it should be a bit more clear (hopefully).
-
Jarek Tkaczyk almost 10 yearsSo the question is how to sync array of tags' ids with organization? Then my answer covers that. Anyway check the edit in a sec.
-
chipit24 almost 10 yearsSorry, I have not even heard of polymorphic relations before and was having some trouble wrapping my head around them. Using sync works perfectly, thanks a lot!!
-
Victor about 9 yearsBy the way, when I use save or attach method it seems like Laravel adds multiple records (like in case you use sync with false flag).
-
Jarek Tkaczyk about 9 years@Victor
save
andattach
may create duplicates.sync
will never do that, with or without the$detach = false
flag. -
Saugat Thapa almost 7 years@JarekTkaczyk does the values insert on tagables table too by laravel using sync??
-
Jarek Tkaczyk almost 7 years@SaugatThapa have you tried? What result did you get?
-
Saugat Thapa almost 7 years@JarekTkaczyk updated_at and created_aat didnt have timestamp inserted