Lara Zettel
Lara Zettel

Reputation: 11

Laravel multiple relations

First of all I'm new at Laravel, I have already read some tutorials and a lot of the docs but now i am by an Problem where i can't find a solution.

I have three tables: post, post_adv_option, adv_option.

So the relationship between these tables would be:

Here is my code I am using:

Models

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 {

}

Tables

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        |
----------------------------------------

Controller

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

Result My current output looks something like this

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"
        ]
    ]
]

But what i need is:

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
        ]
    ]
]

How can I call the relation from Post with PostAdvancedOptions AND AdvancedOption

.. and order the post_advanced_options by AdvancedOption.sort

Upvotes: 1

Views: 180

Answers (3)

heisenberg
heisenberg

Reputation: 912

If the relation is one to Many, then you can keep the foreign key in the child table ( in this case , the AdvanceOptions save the Post primary key ).

Since you define the relationship like that , I recommend to fix the database schema, the AdvanceOption saved the parent Post primary key like this :

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



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

and then the models looks like this :

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

and finally, to find the result you want :

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

Upvotes: 0

Samuel Mercado
Samuel Mercado

Reputation: 61

I'm also relative new to Laravel, but if you only need the AdvancedOptions info, you could use the "Has Many Through" in your Post model:

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

Or if you want to implement the pivot table as mentioned by Ross Edman, then you should move the "value" from PostAdvancedOption table to AdvancedOption

Upvotes: 0

Ross Edman
Ross Edman

Reputation: 823

Currently you have your tables set up for a Many To Many relationship but your models are not setup correctly to have a Many To Many relationship. You would need something like this:

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

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

You do not need a model for PostAdvancedOptions because that is your pivot table and is not a model but just connecting the relationships. Whenever you tell Laravel that a model belongsToMany it automatically looks for a certain pivot table. That pivot table would be advanced_option_post and would have the columns of id, advanced_option_id and post_id. You can also override this to be named something else if you need as well.

You can read more about Many To Many relationships here.

Upvotes: 3

Related Questions