【问题标题】:How to save entries in many to many polymorphic relationship in Laravel?如何在 Laravel 中保存多对多多态关系中的条目?
【发布时间】:2014-07-16 18:09:26
【问题描述】:

我有一个 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);
});

当我视图中的表单被提交时,下面的路由会捕获它来更新组织模型...

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') 只是一个标签 ID 的数组,格式为

["1","6","8"]

如何使用它来将标签与组织相关联?

我还为使用多态关系的组织设置了 cmets,我只是这样做...

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!');
});

但是,当我想将一个或多个标签与组织相关联时,多对多的多态关系并不那么简单。

感谢任何帮助,谢谢!

【问题讨论】:

    标签: laravel-4 eloquent polymorphic-associations


    【解决方案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!');
    });
    

    【讨论】:

    • 这对我没有帮助。你能举例说明我如何在我的情况下使用它吗?我已经更新了我的问题,所以它应该更清楚(希望如此)。
    • 那么问题是如何将标签的 id 数组与组织同步?然后我的回答涵盖了这一点。无论如何,请在几秒钟内检查编辑。
    • @Victor saveattach 可能会创建重复项。 sync 永远不会这样做,无论有没有 $detach = false 标志。
    • @JarekTkaczyk 是否也通过 laravel 使用同步将值插入到 tagables 表中??
    • @SaugatThapa 你试过了吗?你得到了什么结果?
    猜你喜欢
    • 2017-08-14
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 2015-02-15
    • 2014-11-21
    • 2021-08-09
    • 2021-10-18
    • 1970-01-01
    相关资源
    最近更新 更多