Laravel多重关系

时间:2014-10-20 17:06:24

标签: php laravel laravel-4

首先,我是 Laravel 的新手,我已经阅读了一些教程和很多文档,但现在我遇到了一个无法找到解决方案的问题。

我有三个表:post,post_adv_option,adv_option。

所以这些表之间的关系是:

  • post to post_adv_option:One-to-Many
  • post_adv_option to adv_option:One-to-One

这是我正在使用的代码:

模型

class Post extends Eloquent {
   public function postAdvancedOptions() {
      return $this->hasMany('PostAdvancedOptions','post_id');
   }
}

class PostAdvancedOption extends Eloquent {
   public function AdvancedOption() {
      return $this->hasOne('AdvancedOption','id','advanced_option_id');
   }
}

class AdvancedOption extends Eloquent {

}

表格

Post Table
------------------------------  
| id | title | content | ... |
------------------------------
| 1  | AAAAA | aaaaaaa | ... |
------------------------------
| 2  | BBBBB | bbbbbbb | ... |
------------------------------
| .  | ..... | ....... | ... |
------------------------------

PostAdvancedOption Table 
---------------------------------------------
| id | post_id | advanced_option_id | value |
---------------------------------------------
| 1  | 1       | 2                  | xxxxx |
---------------------------------------------
| 2  | 2       | 1                  | aaaaa |
---------------------------------------------
| 3  | 2       | 4                  | bbbbb |
---------------------------------------------
| 4  | 2       | 5                  | xxxxx |
---------------------------------------------

AdvancedOption Table 
----------------------------------------
| id | name      | sort  | description |
----------------------------------------
| 1  | abc       | 0     | desc        |
----------------------------------------
| 2  | def       | 2     | desc        |
----------------------------------------
| 3  | ghi       | 1     | desc        |
----------------------------------------
| .  | ......... | .     | desc        |
----------------------------------------
| 9  | mno       | 8     | desc        |
----------------------------------------

控制器

$postArray = Post::with('postAdvancedOptions')->where('id', '=', $id)->get()->toArray();

结果 我当前的输出看起来像这样

array(3) [
array(15) [
    'id' => integer 64
    'title' => string (19) "test"
    'content' => string (6) "lorem ipsum"        
    'post_advanced_options' => array(3) [
        array(4) [
            'id' => integer 34
            'post_id' => integer 64
            'advanced_option_id' => integer 1
            'option' => string (3) "xxx"
        ]
        array(4) [
            'id' => integer 35
            'post_id' => integer 64
            'advanced_option_id' => integer 1
            'option' => string (3) "yyy"
        ]
        array(4) [
            'id' => integer 36
            'post_id' => integer 64
            'advanced_option_id' => integer 6
            'option' => string (3) "vvv"
        ]
    ]
]

但我需要的是:

array(3) [
array(15) [
    'id' => integer 64
    'title' => string (19) "test"
    'content' => string (6) "lorem ipsum"        
    'post_advanced_options' => array(3) [
        array(4) [
            'id' => integer 34
            'post_id' => integer 64
            'advanced_option_id' => integer 1
            'option' => string (3) "xxx"

            'name' => string (3) "asd"
            'description' => string (3) "asdasd"
            'sort' => integer 0

        ]
        array(4) [
            'id' => integer 35
            'post_id' => integer 64
            'advanced_option_id' => integer 1
            'option' => string (3) "yyy"

            'name' => string (3) "asd"
            'description' => string (3) "asdasd"
            'sort' => integer 1

        ]
        array(4) [
            'id' => integer 36
            'post_id' => integer 64
            'advanced_option_id' => integer 6
            'option' => string (3) "vvv"

            'name' => string (3) "asd"
            'description' => string (3) "asdasd"
            'sort' => integer 1
        ]
    ]
]

如何使用 PostAdvancedOptions AdvancedOption

调用发布的关系

..并按 AdvancedOption.sort

订购post_advanced_options

3 个答案:

答案 0 :(得分:3)

目前,您已将表设置为“多对多”关系,但您的模型未正确设置为具有“多对多”关系。你需要这样的东西:

class Post extends Eloquent {
   public function options() {
      return $this->belongsToMany('AdvancedOption');
   }
}

class AdvancedOption extends Eloquent {
   public function posts() {
      return $this->belongsToMany('Post');
   }
}

您不需要PostAdvancedOptions的模型,因为这是您的数据透视表,不是模型,只是连接关系。每当你告诉Laravel模型belongsToMany时它会自动查找某个数据透视表。该数据透视表将为advanced_option_post,其列数为idadvanced_option_idpost_id。如果你需要,你也可以覆盖它,以便命名别的东西。

您可以阅读有关“多对多”关系的更多信息here

答案 1 :(得分:0)

我对Laravel也相对较新,但如果您只需要AdvancedOptions信息,则可以使用" Has Many Through"在你的帖子模型中:

class Post extends Eloquent {
    public function AdvancedOptions() {
        return $this->hasManyThrough('PostAdvancedOption', 'AdvancedOption');
    }
}

或者如果你想实现Ross Edman所提到的数据透视表,那么你应该移动"值"从PostAdvancedOption表到AdvancedOption

答案 2 :(得分:0)

如果关系是一对多,则可以将外键保留在子表中(在这种情况下,AdvanceOptions保存Post主键)。

由于您定义了这样的关系,我建议修复数据库模式,AdvanceOption保存了父Post主键,如下所示:

Post Table
------------------------------  
| id | title | content | ... |
------------------------------
| 1  | AAAAA | aaaaaaa | ... |
------------------------------



AdvancedOption Table 
-------------------------------------------------------------------
| id | name      | post_id | value | another advanceoption column |
-------------------------------------------------------------------
| 1  | abc       | 0       |       |                              |
-------------------------------------------------------------------

然后模型看起来像这样:

class Post extends Eloquent {
   public function advanceoption() {
      return $this->hasMany('App\AdvanceOption','post_id');
   }
}

class AdvancedOption extends Eloquent {
   public function post() {
      return $this->belongsTo('App\Post','post_id');
   }
}

最后,找到你想要的结果:

$postArray = Post::find($id)->advanceoption()->get();