Laravel ORM from self referencing table get N level hierarchy 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();
Recursive Eloquent Models
Research led me to this thread that suggested how to get recursive records via hasMany
thus
public function replys()
{
return $this->hasMany(Message::class, 'reply_to', 'id');
}
public function replies()
{
return $this->replys()->with('replies');
}
Did not think it would be this easy however, I was hoping that I could have kept it simple without having to devise a complex raw query statement.
My question now is how does this recursive method stand up to large data sets?
I am creating category model where it has parent of category model itself
Some of your categories don't have a parent, they are root nodes, so you must check it $category->parent
first, then access its properties.
Now, don't use isset
since relation is not set as a property on the object. Use this instead:
if (count($category->parent)) // do something
// or is_null
if (is_null($category->parent));
Also get()
returns collection, what you want is first()
that returns single model.
I suggest you read this answer about recursive relations to make working with your setup easier:
Laravel ORM from self referencing table get N level hierarchy JSON
And also this one, so you know why I suggest count
instead of is_null
to check related model:
Laravel check if related model exists
How to display parent child flat table records as nested list in Php?
You can create a self-referring relationship
class Task extends Model{
public function tasks()
{
return $this->hasMany('App\Task', 'parent');
}
}
in your controller:
$tasks = Task::where('parent',0)->get();
return view ('tasks.index',compact('tasks'));
Then make the view recursive.
<div>
@foreach($tasks as $task)
{{$task->name}}
@if(count($task->tasks))
@include('tasks.index',['tasks' => $task->tasks])
@endif
@endforeach
</div>
(might need some cleaning up to prevent confusing the variable names, but you get the general idea)
Eloquent Parent-Child relationship on same model
You would have to recursively get the children if you have an unknown depth like that.
Another option is to use the nested sets model instead of the adjacency list model. You can use something like baum/baum
package for Laravel for nested sets.
"A nested set is a smart way to implement an ordered tree that allows for fast, non-recursive queries." - https://github.com/etrepat/baum
With this package you have methods like getDescendants
to get all children and nested children and toHierarchy
to get a complete tree hierarchy.
Wikipedia - Nested Set Model
Baum - Nested Set pattern for Laravel's Eloquent ORM
Managing Hierarchical Data in MySQL
Related Topics
Symfony 2 Load Different Template Depending on User Agent Properties
Mask Credit Card Number in PHP
Multidimensional Array to String
Add a Fee to Woocommerce Per Product, Based on Category
Copy Large Files (Over 2 Gb) in PHP
PHP Read File as an Array of Bytes
Codeigniter 2 on Iis with Web.Config File
How to Get All Checkbox Variables Even If Not Checked from HTML to PHP
Inheritance of Static Members in PHP
Wordpress Woocommerce - Use Update_Post_Meta to Add Product Attributes
Compile Error: "G++: Error Trying to Exec 'Cc1Plus': Execvp: No Such File or Directory"
How to Format Messages for Queueing
PHP & Hash/Fragment Portion of Url
But These Conflict with Your Requirements or Minimum-Stability
How to Remove All Numbers from String
How to Check If a Longitude/Latitude Point Is Within a Range of Coordinates