1

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:

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

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

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

And you have to attach those to each other using attach method, eg : $post->AdvancedOption()->attach();
@Ross Edman, Thank you for helpful explanation. My Solution now is a pivot table with function: return $this->belongsToMany('AdvancedOption')->orderBy("sort", "desc")->withPivot(array('value'));
0

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

Comments

0

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();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.