2014-08-27 174 views
1

我正在致力于laravel-4应用程序。目前它很好地融合在一起,我一直在定义数据库各个表之间的关系。不过,我遇到了一个问题,我遇到了麻烦。多对多关系Laravel 4

在我的数据库中有一个资源表和标签表。他们之间有多对多的关系,所以我也有一个resource_tags表,其中有两个表id作为foreign keys

现在,当我基于用户通过表单提供的数据创建资源时,我将创建资源,检查类型并决定一个操作。然后,我检索资源的标签并通过它们进行循环,并创建表格的Tags表项。

我的问题是将信息放入resource_tags表中。有没有一种方法可以使我相对容易地做到这一点?

这是我controller正在处理表单提交:

class SharedResourcesController extends BaseController { 
    //Add a shared Resource to the DB 
    //To do: Error checking and validation. 
    public function handleResource(){ 

     //Create Object 
     $resource = new SharedResource; 
     $resource->title = Input::get('title'); //Title of resource 
     $resource->user_id = Input::get('user_id'); //User who uploads 
     $resource->book_id = Input::get('book_id'); //Book it is associated with 
     $resource->type_id = Input::get('type_id'); //Type of resource 

     //STORE LINKS 
     //if type is link... 1 
     if($resource->type_id == "1"){ 
      $resource->web_link = Input::get('link'); 
     } 
     //if type is video...2 
     if($resource->type_id == "2"){ 
      $resource->vid_link = Input::get('link'); 
     } 
     //UPLOADING 
     //If type is doc...3 
     if($resource->type_id == "3"){ 
      if(Input::hasFile('file')){ 
       $destinationPath = ''; 
       $filename = ''; 
       $file = Input::file('file'); 
       $basename = Str::random(12); 
       $extension = $file->getClientOriginalExtension(); 
       $destinationPath = public_path().'/file/'; 
       $filename = Str::slug($basename, '_').".".$extension;//Create the filename 
       $file->move($destinationPath, $filename); 
       $resource->doc_link = $filename; 
      } 
     } 
     //if type is img...4 
     if($resource->type_id == "4"){ 
      if(Input::hasFile('file')){ 
       $destinationPath = ''; 
       $filename = ''; 
       $file = Input::file('file'); 
       $basename = Str::random(12); 
       $extension = $file->getClientOriginalExtension(); 
       $destinationPath = public_path().'/img/uploads/'; 
       $filename = Str::slug($basename, '_').".".$extension;//Create the filename 
       $file->move($destinationPath, $filename); 
       $resource->img_link = $filename; 
      } 
     } 

     //TAGS 
     //Get the tags 
     $tags = Array(); 
     $tags = explode(',', Input::get('tags')); 
     foreach($tags as $tag){ 
      //Create a new Tag in DB - TO DO: Only Unique TAGS 
      $newTag = new Tag; 
      $newTag->name = $tag; 
      $newTag->save(); 
      //Enter to resource tags 
     } 

     //Entry to resouce_tags 

     //Save Object 
     $resource->save(); 
     return Redirect::action('[email protected]')->with('success', 'Resouce Created!'); 

     //Any errors return to Form... 
    } 
} 

MODELS

class SharedResource extends Eloquent{ 
    //set up many to many 
    public function tags(){ 
     return $this->belongsToMany('Tag'); 
    } 

class Tag extends Eloquent{ 
    //set up many to many 
    public function sharedResources(){ 
     return $this->belongsToMany('SharedResource'); 
    } 

我知道有很多的验证方面的缺失和错误处理,但我只是想获得flo工作,我可以在以后修改它。我会很感激任何帮助。

+1

只是澄清一下,你问你是否可以一次将多个标记保存到特定的资源,同时也将这些枢轴关系插入到resource_tag数据透视表中? – Patrick 2014-08-27 12:57:09

+0

是的,这正是我需要做的 – Javacadabra 2014-08-27 12:57:48

+0

顺便说一下,据我所知,如果你希望Laravel能够实现它,你的数据透视表应该使用单数:'resource_tag'而不是'resource_tags'。也就是说,你显然已经在重写表名,因为你的'resources'表的模型被称为'SharedResource'。 – alexrussell 2014-08-27 14:45:18

回答

0

您是否可以为两个模型添加代码?你有他们定义的关系吗?

例如:

class Resource extends Eloquent { 

    public function tags() 
    { 
     return $this->belongsToMany('tag'); 
    } 
} 

class Tag extends Eloquent { 

    public function resources() 
    { 
     return $this->belongsToMany('resource'); 
    } 
} 
1

所有您需要做的是建立或抢资源,并建立或抢标签然后调用saveMany资源上的标签的关系,并通过一个(伪代码示例):

$resource = Resource::create(['name' => 'Resource 1']); 
$tag = []; 
for ($i = 5; $i > 0; $i--) { 
    $tag = Tag::create(['name' => 'Tag '.$i]); 
    array_push($tags, $tag); 
} 
$resource->tags()->saveMany($tags); 

$ tag必须是一个Tag对象的数组,并且关系中的saveMany调用将为您处理数据透视表插入。您应该在资源表中使用资源1资源,标记表中包含5个标记,并在resource_tag表中保存5个记录。