Reputation: 11
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
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
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
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