Как сохранить записи во многих полиморфных отношениях в Laravel?
У меня есть модель Org и модель Tag. Я хочу связать теги с организациями. Мои таблицы базы данных и модели Eloquent настроены так...
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');
}
}
На мой взгляд, у меня есть форма с многократным полем выбора, где пользователь может выбрать теги, которые он/она хочет связать с организацией...
...
{{ Form::select('tags[]', $tag_options, null, array(
'multiple',
'data-placeholder' => 'Select some tags'))
}}
...
... И $tag_options поступает из файла routes.php...
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);
});
Когда форма в моем представлении будет отправлена, следующий маршрут заставит ее обновить модель org...
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!');
});
Теперь Input:: get ('tags') - это всего лишь массив идентификаторов тегов, формы
["1","6","8"]
Как я могу использовать это для связывания тегов с организацией?
У меня также есть комментарии для организаций, использующих полиморфные отношения, где я просто делаю это...
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!');
});
Однако это не так просто с полиморфными отношениями "много ко многим", когда я хочу связать один или несколько тегов с организацией.
Любая помощь приветствуется, спасибо!
Ответы
Ответ 1
Вы можете использовать все методы belongsToMany
для этого, поскольку полиморфное много-ко-многим расширяет это отношение:
// 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)
Все эти методы работают в обоих направлениях.
<сильные > Примеры:
$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
Ваш случай:
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!');
});