I am using LARAVEL 4
with MySQL
back-end.
I have a self-referencing
table with columns id, name, type
and parent
.
Here, parent
is foreign-key
of the column Id
. The data in table is as below :
id name type parent
1 General group NULL
2 What is..? question 1
3 aa answer 2
4 bb answer 2
5 cc answer 2
6 How is..? question 1
7 ba answer 6
8 bb answer 6
9 Where is..? question 4
10 ca answer 9
11 cb answer 9
12 Who is..? question 6
13 da answer 12
14 db answer 12
15 Specific group NULL
16 When is..? question 15
17 ea answer 16
18 eb answer 16
19 Whome is..? question 2
20 fa answer 19
21 fb answer 19
22 fc answer 19
I want a function that return nested JSON
using this relational data. For example :
[{
"id" : 1,
"name" : "Geneal",
"type" : "group",
"children" : [{
"id" : 2,
"name" : "What is..?",
"type" : "question",
"children" : [{
"id" : 3,
"name" : "aa",
"type" : "answer"
},
{
"id" : 4,
"name" : "bb",
"type" : "answer"
},
{
"id" : 5,
"name" : "cc",
"type" : "answer"
}]},
{
"id" : 6,
"name" : "How is..?",
"type" : "question",
"children" : [{
"id" : 7,
"name" : "ba",
"type" : "answer"
},
{
"id" : 8,
"name" : "bb",
"type" : "answer"
}]
}]
... and so on
}]
I have created a model
named Survey
as below :
class Survey extends BaseModel{
protected $table = 'questions';
protected $softDelete = false;
public function parent()
{
return $this->belongsTo('Survey', 'parent');
}
public function children()
{
return $this->hasMany('Survey', 'parent');
}
}
and called it in controller
with :
$user = Survey::all();
$parent = $user->parent()->first();
$children = $user->children()->get();
But I am not getting the proper result as I have mentioned in JSON
above.
print_r($parent->toJson());
gives records with one level hierarchy only (i.e group and questions, not answers).
while
print_r($children ->toJson());
Gives only questions (Not groups and answers).
I want the whole self-referencing data in nested JSON format with N level of hierarchy.
I also have tried
$user = Survey::with('parent', 'children')->get();
But found same as $parent above.
Is there anyway I can get the desired result?
Thanks in advance..
The Eloquent ORM included with Laravel provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding "Model" which is used to interact with that table.
Introduction to Laravel Response JSON. Laravel Response JSON, the Laravel framework has been in demand for the last few years. It has been able to garner a sizeable portion of the development framework market. The reasons are plenty. One of the most important features of the framework has been its expressive command line methods.
Back-end: Migration + Model To create a JSON field, all we need to do in Laravel migration is use ->json () method: Schema::create ('products', function (Blueprint $table) { $table->increments ('id'); $table->string ('name'); $table->decimal ('price', 15, 2); $table->json ('properties'); $table->timestamps (); $table->softDeletes (); });
Much has been said about the Laravel framework library. This is a library that stores a vast amount of information. It is easy to access and as I had mentioned earlier expressive enough to provide multiple options for the same functionality. Let’s take for example the subject of this article: Laravel Response JSON.
Here's how you manually retrieve nested relations:
$collection = Model::with('relation1.relation2.relation3')->get();
So in your case it would be:
$surveys = Survey::with('children.children.children')->get();
Obviously this will do the job when the relations are fixed, but it's not the way to go for a recursive relation to the same table.
Fortunately, you can make such relation recursive, then all you need to retrieve whole tree is this:
$surveys = Survey::with('childrenRecursive');
However, I wouldn't load parent for each row this way.
So here's all you need:
// Survey model
// loads only direct children - 1 level
public function children()
{
return $this->hasMany('Survey', 'parent');
}
// recursive, loads all descendants
public function childrenRecursive()
{
return $this->children()->with('childrenRecursive');
// which is equivalent to:
// return $this->hasMany('Survey', 'parent')->with('childrenRecursive);
}
// parent
public function parent()
{
return $this->belongsTo('Survey','parent');
}
// all ascendants
public function parentRecursive()
{
return $this->parent()->with('parentRecursive');
}
EDIT: To get real tree structure, first query must be limited to only root nodes:
$surveys = Survey::with('childrenRecursive')->whereNull('parent')->get();
so simple!!!
1- load your 'children' relation in your 'children' relation in your model like this :
class Survey extends BaseModel{
protected $table = 'questions';
protected $softDelete = false;
public function parent()
{
return $this->belongsTo('Survey', 'parent');
}
public function children()
{
// change this: return $this->hasMany('Survey', 'parent');
return $this->hasMany('Survey', 'parent')->with('children);
}
}
2- you just need add clouser function to your relation like this:
$surveys = Survey::with(['children' => function($q) {
$q->with('children');
},
'parent' => function($q) {
$q->with('parent');
});
then you can access to your nested children in your result like this:
$surveys->children
and unlimited nesting :
$surveys->children->first()->children
and so on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With