franzose / closuretable Goto Github PK
View Code? Open in Web Editor NEWAdjacency List’ed Closure Table database design pattern implementation for the Laravel framework.
License: MIT License
Adjacency List’ed Closure Table database design pattern implementation for the Laravel framework.
License: MIT License
I'm trying to implement Closure Table in a project and just found some errors in the documentation:
$page->appendChild($newChild);
should be
$page->addChild($newChild);
$page->appendChildren([$newChild, $newChild2]);
should be
$page->addChildren([$newChild, $newChild2]);
Page::find(11)->makeRoot();
doesn't work, needs paramter $position, so it should read something like
Page::find(11)->makeRoot(0);
When you run
$array = [
[
'id' => 90,
'name' => 'About',
'position' => 0,
'children' => [
[
'id' => 93,
'name' => 'Testimonials'
]
]
],
[
'id' => 91,
'name' => 'Blog',
'position' => 1
],
[
'id' => 92,
'name' => 'Portfolio',
'position' => 2
],
];
$pages = Page::createFromArray($array);
You get the error:
[Illuminate\Database\QueryException]
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update
a child row: a foreign key constraint fails (`DATABASE`.`TABLE`, C
ONSTRAINT `TABLE_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENC
ES `TABLE` (`id`)) (SQL: insert into `TABLE` (`position`, `real_d
epth`) values (0, 0))
I generated the database using:
php artisan closuretable:make --entity=page
All of a sudden I'm getting this error…
Declaration of Franzose\ClosureTable\Entity::performUpdate() should be compatible with Illuminate\Database\Eloquent\Model::performUpdate(Illuminate\Database\Eloquent\Builder $query)
The declaration in Entity looks like this:
protected function performUpdate($query)
And in core:
protected function performUpdate(Builder $query)
with this one i have an error (Categorie is an Entity Model)
$categorie = Categorie::find(24);
$newChild = new Categorie(array(
'libelle' => 'test'
));
$categorie->appendChild($newChild);
The new function works fine (insert is make in db) but appendChild return :
"Using $this when not in object context"
Here is the tree that I am trying to build:
$tree = [
[
'name' => 'book',
'table' => 'books',
],
[
'name' => 'electronic',
'table' => 'electronics',
],
[
'name' => 'furniture',
'table' => 'furniture',
],
[
'name' => 'housing',
'table' => 'housing',
],
[
'name' => 'ride',
'table' => 'rides',
],
[
'name' => 'ticket',
'table' => 'tickets',
],
[
'name' => 'misc',
'table' => 'misc',
],
[
'name' => 'promotion',
'table' => 'promotions',
],
[
'name' => 'tutor',
'table' => 'tutors',
],
[
'name' => 'clothing',
'table' => 'clothing',
'children' =>
[
[
'name' => 'men',
'table' => null,
'children' =>
[
[
'name' => 'shoes',
'table' => null,
],
[
'name' => 'shorts',
'table' => null,
],
[
'name' => 'pants',
'table' => null,
],
[
'name' => 'belts',
'table' => null,
],
[
'name' => 'shirts',
'table' => null,
],
[
'name' => 'sweaters',
'table' => null,
],
[
'name' => 'jackets',
'table' => null,
],
[
'name' => 'hats',
'table' => null,
],
[
'name' => 'sunglasses',
'table' => null,
],
[
'name' => 'business',
'table' => null,
],
[
'name' => 'misc',
'table' => null,
],
],
],
[
'name' => 'women',
'table' => null,
'children' =>
[
[
'name' => 'shoes',
'table' => null,
],
[
'name' => 'shorts',
'table' => null,
],
[
'name' => 'pants',
'table' => null,
],
[
'name' => 'belts',
'table' => null,
],
[
'name' => 'shirts',
'table' => null,
],
[
'name' => 'sweaters',
'table' => null,
],
[
'name' => 'jackets',
'table' => null,
],
[
'name' => 'hats',
'table' => null,
],
[
'name' => 'sunglasses',
'table' => null,
],
[
'name' => 'dresses',
'table' => null,
],
[
'name' => 'business',
'table' => null,
],
[
'name' => 'misc',
'table' => null,
],
],
],
],
],
];
Category::createFromArray($tree);
When calling createFromArray it inserts all of the items in the array but doesn't correctly set the parent_id and double inserts some items. Here is what the table looks like after inserting the above tree.
Notice how men and women should be a child of clothing but they are inserted as roots. Additionally notice how the children of men and women are inserted as children but additionally inserted as roots.
Hi, I have never used closure tables before, and I am considering to use your class in my new Laravel project. I am a bit confused about which columns must be in each of my tables. Could you provide an example migration, please?
I Have just update with composer, i have this message :
Declaration of Franzose\ClosureTable\Entity::performUpdate() should be compatible with that of Illuminate\Database\Eloquent\Model::performUpdate()
i make a composer update this morning (in france :)
i create 2 roots (categorie 1 and categorie 2) like this
$categorie = new Categorie(array(
'libelle' => 'Categorie 1'
));
$categorie->appendChild($categorie);
$categorie = new Categorie(array(
'libelle' => 'Categorie 2'
));
$categorie->appendChild($categorie);
::tree and ::roots works fine.
I create 2 childs for the first root like this
$categorie = Categorie::find(2);
$newChild = new Categorie(array(
'libelle' => 'sous categorie 1-1'
));
$categorie->appendChild($newChild);
$newChild = new Categorie(array(
'libelle' => 'sous categorie 1-2'
));
$categorie->appendChild($newChild);
everything seems ok in database
::roots works fine but ::tree return only the 2 roots
same results with mysql
It would be really useful to have a way to get full ClosureTable tree with eagerly loaded relationships data. Right now, I need a way to get the full tree with lang data from another table, and it would be great to write something like Categories::with('langs')->get_tree()
to get everything in one line.
There's still an error
10) ClosureTableTestCase::testRemoveChild
Exception: SQLSTATE[23000]: Integrity constraint violation: 19 pages.position may not be NULL (SQL: insert into "pages" ("title", "excerpt", "content", "language", "updated_at", "created_at") values (?, ?, ?, ?, ?, ?)) (Bindings: array (
0 => 'Test Title',
1 => 'Test Excerpt',
2 => 'Test content',
3 => 'en',
4 => '2013-10-04 22:56:25',
5 => '2013-10-04 22:56:25',
))
Caused by
PDOException: SQLSTATE[23000]: Integrity constraint violation: 19 pages.position may not be NULL
The code of the test is this:
$page = new Page(array(
'title' => 'Test Title',
'excerpt' => 'Test Excerpt',
'content' => 'Test content',
'language' => 'en'
));
$page->save();
So it looks like that creating a page with new Page()
doesn't fill the position
column, while with Page::create()
everything works correctly.
Hello,
You should create a license file containing the license this library is under. It's up to you, but I generally like the MIT license myself.
Check http://choosealicense.com/ if you need help figuring out which one makes the most sense to you.
Hi there,
does ClosureTable still work with 5.3.10? When i try to run php composer.phar update i get an error telling me minimum is 5.4 now when just a few days ago it was fine.
Thanks!
Register on https://travis-ci.org/ and add this project to your account.
Then modify the README.md to include something like
[![Build Status](https://travis-ci.org/tomzx/ClosureTable.png)](https://travis-ci.org/tomzx/ClosureTable)
To display the status of your code from travis-ci.org builds, which looks something like this:
Hello,
If migrations are generated within the same second they will possibly execute in the wrong order and it'll be impossible to run them properly since there's a dependency for the closure_table FK to the entity table.
It is going to be necessary to generate their name so that they are executed in the proper order.
Hello,
What is supposed to be the behavior of setting positions which do not make sense?
For instance, let say you have a tree as such:
Now let say you decide to moveTo(5000)
Item D. All newer items would end up with a position = 5000 + x, meanwhile there would be a huge hole between position 1 and 4999.
Would it make more sense to set the positions to be inclusive between 0 and the current number of siblings? Otherwise, what is the use case of having unlimited freedom on the position? Furthermore this also means that it is possible to set negative positions...
Hey,
Is there a way to get already sorted tree? From what I can see it's returning the tree ommiting the position column.
Trying to follow the instructions in the customization section (https://github.com/franzose/ClosureTable#customization) -- BUT per phpdoc, there's this issue: http://php.net/manual/en/language.oop5.interfaces.php#102755.
And sure enough, when you follow the suggestion in the guide, PHP squeaks: "Cannot inherit previously-inherited or override constant <CONTANT_NAME_IN_CLOSURE_TABLE> -- what's going on here?
Hello!
Please consider the following seeds:
<?php
class NodeSeeder extends Seeder {
public function run()
{
// Rooot
Node::create(
array (
'description' => '/'
)
);
// Root -> Impressum
Node::create(
array(
'description' => 'Impressum'
)
);
// Root -> Contact
Node::create(
array(
'description' => 'Contact'
)
);
// Root -> A
Node::create(
array(
'description' => 'A'
)
);
// Root -> B
Node::create(
array(
'description' => 'B'
)
);
$this->setUpPaths();
}
private function setUpPaths()
{
// Root
Node::find(2)->moveTo(Node::find(1));
Node::find(3)->moveTo(Node::find(1));
Node::find(4)->moveTo(Node::find(1));
}
}
You see, I wanna build a tree-structure (manually).
Node 2, 3 and 4 should be childs of Node 1.
But I get this:
[Exception]
SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in '(`dabatase`.`nodes`.`position` - 1)' (SQL: update `nodes` set `position` = `position` - 1, `updated_at`
= ? where `nodes`.`deleted_at` is null and `id` in (?) and `position` in (?, ?)) (Bindings: array (
0 => '2013-10-04 11:46:26',
1 => '2',
2 => 0,
3 => 1,
))
As well as this:
[PDOException]
SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in '(`database`.`nodes`.`position` - 1)'
I made the tables as you specified them in the docs (and added additional columns I need of course.)
The problem here is that position is set to be unsigned! (As you did in the docs)
If it is not unsigned, the position of node 2 ("impressum") is set to -1 and everything works.
So either one has to manually update the position or we need an additional check here...
Okay, this may not be an issue at all, but as far as I understood (and implemented it myself) the depth of a certain Entity/Node should be the same on all the entries where it is a descendant within the closure.
For example,
I create two nodes, one is a root, the other is one as well (at first).
So we have
id ancestor descendant depth
1 1 1 0
2 2 2 0
Now let's move node #2 so it's a descendant of #1:
Node::find('2')->moveTo('1');
And have a look at the closure:
id ancestor descendant depth
1 1 1 0
2 2 2 0
3 1 2 1
Line 1 and 3 are correct, but shouldn't two be updated? I mean Node two is an ancestors of node two, but it´s depth should now be 1 as well (as the whole node was moved, not only the closure-entry!)
So what I'm saying is: if you move a node, I think it would be right to update each row in the closure where it is a descendant (and an ancestor, of course)
Am I wrong here? Is there something I'm missing?
Cheers,
The Dancing Bard
While deleting data from main table corresponding datum are not removed from the closure table
First of all I want to add that I'm not sure if my data is correct. There's a few things I noticed when creating my items in the database…
Entries in grades_closure were created, but when moving an item to a parent, only the first one succeeded without error. Every other item added under the same parent throws an error because it tried to add a signed value to the position column.
Let's say there was a sibling under a parent with position 0
, whenever I moved another sibling under the same parent, it would try to add it with a position -1
It did however end up adding the new item to the database and the position seems to end up ok.
The second thing I've noticed is that whenever an item was moved to the parent (let's say an item with id 10
was moved to a parent with id 20
), 2 entries existed in grades_closure:
ancestor 10, descendant 10, depth 0
ancestor 20, descendant 10, depth 1
When requesting the tree with these values in the database, loading was very slow (about a second or two) while there are less than 100 items in the database. On top of that, it showed no tree hierarchy.
When removing these items in grades_closure that referenced themselves, load time when requesting the entire tree was OK again, but now it only showed the parents. From the documentation, I get the impression that it should retrieve the entire tree, parents + siblings.
However, requesting the children of a specific parent works without problems, and I can also request the parent of a given child.
Am I doing something wrong or is this intended behaviour?
Also, the documentation left me guessing a bit as to how I go about creating the actual data, I'm sure it's obvious enough when it works, but when something fails, I was left guessing if I went about it the wrong way.
I'd be happy to add to the documentation if I know the correct approach.
For your convenience, here's an sql dump of the two tables: https://dl.dropboxusercontent.com/u/139621/30-09-13_grades.sql
Hello,
I think it should be possible to optimize the code that generates the entities_closure entries. Currently, the code generates a query that looks like this
insert into "entities_closure" ("ancestor", "depth", "descendant")
select 16 as "ancestor", 2 as "depth", 19 as "descendant"
union
select 17 as "ancestor", 1 as "depth", 19 as "descendant"
union
select 19 as "ancestor", 0 as "depth", 19 as "descendant"
It should be possible to do something like creating a subquery that creates the current closure table for the parent node of the node to be inserted, and specify for all those entries that depth = depth + 1 and the descendant is the new node instead of the parent.
Let see if that is something we can do.
ClosureTable / src / Franzose / ClosureTable / Generators / stubs / migrations / closuretable.php
In this file there is missing ");" in line 30.
it will be great to have ->json() feature for populate tree or other objet witch can load json data
After launching php artisan closuretable:make --entity=categories one of the migration files is for our non-closure table:
public function up()
{
Schema::create('categories', function(Blueprint $table){
$table->increments('id');
$table->integer('parent_id')->unsigned();
$table->integer('position', false, true);
$table->integer('real_depth', false, true);
$table->softDeletes();
$table->foreign('parent_id')->references('id')->on('categories');
});
}
Migration goes well and after inserting first row into a table I get constrain violation error - you cannot add constrain on parent_id referancing id, because there is no other row in the table. If I alter column parent_id to accept nulls everything works ok.
I believe there is missing nullable() for parent_id column in up() function for non-close table. I think it was intentended that way, because for example the Entity class has function:
/**
* Retrieves root (with no ancestors) models.
*
* @param array $columns
* @return \Franzose\ClosureTable\Extensions\Collection
*/
public static function getRoots(array $columns = ['*'])
{
/**
* @var Entity $instance
*/
$instance = new static;
return $instance->whereNull($instance->getParentIdColumn())->get($columns);
}
which looks for nulls in the table.
::roots() returns SQL error :
SQLSTATE[42703]: Undefined column: 7 ERREUR: la colonne « parentid » n'existe pas LINE 1: ...ies_closure WHERE categories_closure.descendant = parentId A... ^ (SQL: select distinct "categories"., "categories_closure"."ancestor" as "parentId" from "categories" inner join "categories_closure" on "categories_closure"."ancestor" = "categories"."id" and "categories_closure"."descendant" = "categories"."id" where "categories"."deleted_at" is null group by "categories"."id" having (SELECT COUNT() FROM categories_closure WHERE categories_closure.descendant = parentId AND categories_closure.depth > 0) = 0) (Bindings: array ( ))
There's something wrong with the return value of prepareTestedSiblings()
because everytime it's called i get a InvalidArgumentException: Value must be provided.
error message.
I have an issue with xdebug and i can't dig deeper into this at the moment, anyway i noticed that if there's an error a test execution is halted, because a $this->assertEquals(true, false)
dropped below the assignment is never evaluated.
Before writing the test for filteredTree(), i ran the tests and i got these errors, is it ok or am i missing something?
1) ClosureTableTestCase::testDelete
InvalidArgumentException: Value must be provided.
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Query/Builder.php:281
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Eloquent/Builder.php:755
/vendor/franzose/closure-table/src/models/Entity.php:481
/vendor/franzose/closure-table/src/models/Entity.php:481
/vendor/franzose/closure-table/src/models/Entity.php:690
/vendor/franzose/closure-table/src/models/Entity.php:680
/vendor/franzose/closure-table/src/models/Entity.php:887
/vendor/franzose/closure-table/src/models/Entity.php:962
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Eloquent/Model.php:1066
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Eloquent/Model.php:794
/vendor/franzose/closure-table/tests/ClosureTableTestCase.php:165
2) ClosureTableTestCase::testAncestors
Argument 1 passed to Franzose\ClosureTable\Entity::ancestors() must be of the type array, boolean given, called in /vendor/franzose/closure-table/tests/ClosureTableTestCase.php on line 249 and defined
/vendor/franzose/closure-table/src/models/Entity.php:198
/vendor/franzose/closure-table/tests/ClosureTableTestCase.php:249
3) ClosureTableTestCase::testHasPrevSiblings
InvalidArgumentException: Value must be provided.
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Query/Builder.php:281
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Eloquent/Builder.php:755
/vendor/franzose/closure-table/src/models/Entity.php:481
/vendor/franzose/closure-table/src/models/Entity.php:481
/vendor/franzose/closure-table/src/models/Entity.php:628
/vendor/franzose/closure-table/src/models/Entity.php:618
/vendor/franzose/closure-table/tests/ClosureTableTestCase.php:477
4) ClosureTableTestCase::testCountPrevSiblings
InvalidArgumentException: Value must be provided.
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Query/Builder.php:281
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Eloquent/Builder.php:755
/vendor/franzose/closure-table/src/models/Entity.php:481
/vendor/franzose/closure-table/src/models/Entity.php:481
/vendor/franzose/closure-table/src/models/Entity.php:628
/vendor/franzose/closure-table/tests/ClosureTableTestCase.php:486
5) ClosureTableTestCase::testHasNextSiblings
InvalidArgumentException: Value must be provided.
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Query/Builder.php:281
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Eloquent/Builder.php:755
/vendor/franzose/closure-table/src/models/Entity.php:481
/vendor/franzose/closure-table/src/models/Entity.php:481
/vendor/franzose/closure-table/src/models/Entity.php:670
/vendor/franzose/closure-table/src/models/Entity.php:660
/vendor/franzose/closure-table/tests/ClosureTableTestCase.php:514
6) ClosureTableTestCase::testCountNextSiblings
InvalidArgumentException: Value must be provided.
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Query/Builder.php:281
/vendor/franzose/closure-table/vendor/illuminate/database/Illuminate/Database/Eloquent/Builder.php:755
/vendor/franzose/closure-table/src/models/Entity.php:481
/vendor/franzose/closure-table/src/models/Entity.php:481
/vendor/franzose/closure-table/src/models/Entity.php:670
/vendor/franzose/closure-table/tests/ClosureTableTestCase.php:523
FAILURES!
Tests: 41, Assertions: 132, Errors: 6.
Hi
Iam getting this error on PHP 5.3
Call to undefined method Franzose\ClosureTable\Extensions\QueryBuilder::clampPosition()
in the file franzose/closure-table/src/Franzose/ClosureTable/Models/Entity.php arround the line 271
Inside the method: public static function boot()
This happens whe i make this call:
$model->moveTo(0, $parent);
$model is a class that extends Entity
$parent is the id of my parent category
how can i fix this?
thanks
[2014-09-22 01:38:45] production.ERROR: exception 'Symfony\Component\Debug\Exception\FatalErrorException' with message 'Call to a member function getTable() on a non-object' in /var/www/iysv2/branches/vendor/franzose/closure-table/src/Franzose/ClosureTable/Models/Entity.php:343
Stack trace:
#0 [internal function]: Illuminate\Exception\Handler->handleShutdown()
#1 {main} [] []
Hi.
after I update laravel with composer this error occured :
Call to undefined method Franzose\ClosureTable\Extensions\QueryBuilder::echo_debug()
I changed echo_debug function in Franzose\ClosureTable\Models\Entity.php
to protected and the problem solved.
I think this error occurs because in updated laravel the function that we passed to static::saving() in line 267 execute in Builder class.
@franzose, i'm working on the tests but i don't get why the position
field is not populated on Page::create()
and i get many sql exceptions about pages.position may not be NULL
.
If i change in the Schema::create('pages')
the position
column creation to $table->integer('position', false, true)->nullable();
i can avoid all these errors but i don't think this is a good solution.
I'm running commit abf7a98 (as current master is broken for adding children, see #103)
I add a couple of nodes,
array(
0 => array(
'id' => 8,
'parent_id' => NULL,
'position' => 0,
'real_depth' => 0,
'name' => 'Sport',
),
1 => array(
'id' => 9,
'parent_id' => NULL,
'position' => 1,
'real_depth' => 0,
'name' => 'Culture',
)
)
So far so good. Now I add a child to id 9 by calling addChild
on 9 with a new, unsaved node. Seems to work well:
array(
0 => array(
'id' => 8,
'parent_id' => NULL,
'position' => 0,
'real_depth' => 0,
'name' => 'Sport',
),
1 => array(
'id' => 9,
'parent_id' => NULL,
'position' => 1,
'real_depth' => 0,
'name' => 'Culture',
'children' => array(
0 => array(
'id' => 10,
'parent_id' => 9,
'position' => 0,
'real_depth' => 1,
'name' => 'Drama',
)
)
)
)
Now I want to move that most recent tag out to be a root node. Here's where things break a bit. The positions should be 0, 1, 2 instead of 0, 2, 3?
array(
0 => array(
'id' => 8,
'parent_id' => NULL,
'position' => 2,
'real_depth' => 0,
'name' => 'Sport',
),
1 => array(
'id' => 9,
'parent_id' => NULL,
'position' => 3,
'real_depth' => 0,
'name' => 'Culture',
),
2 => array(
'id' => 10,
'parent_id' => NULL,
'position' => 0,
'real_depth' => 0,
'name' => 'Drama',
)
)
Unhandled Exception
Message:
Cannot use object of type stdClass as array
Location:
./bundles/closuretable/closuretable.php on line 193
Solution
foreach ($raw as $i => $e)
{
if (**$e->{static::$parent_key}** == $index)
{
unset($raw[$i]);
$result[] = array_merge($e, array('children' => static::_make_multi_array($raw, $e[static::$key])));
}
}
Hi,
I'm currently interested in using your library in my project, so I forked your repository, installed all the composer dependencies and then ran PHPUnit. There was a single test failing, which is the following:
Franzose\ClosureTable\Tests\EntityTestCase::testAddSiblingsFromPosition
Failed asserting that '13' matches expected 16.
I'm not familiar with the code yet, but I'll be running git-bisect to figure out at which point that error appeared.
Side note:
I see you have a travis.yml file, but I wasn't able to find your builds on travis-ci.org. Any reason in particular?
You can use something like
[![Build Status](https://travis-ci.org/tomzx/ClosureTable.png)](https://travis-ci.org/tomzx/ClosureTable)
To display the status of your code from travis-ci.org builds, which looks something like this:
See https://travis-ci.org/tomzx/ClosureTable/builds/21892614 for more details.
In a project that i'm developing, every user has a tree of categories that he can define. Using tree()
i fetch every record in the table, so i modified the method to accept three parameters: $field
, $operator
and $value
, so that i can add a where
clause in the query.
I would like to propose this as a commit, but would it be better to have a modified tree()
function or a filteredTree()
?
GetChildren() only retrives the direct Children but in order to get All children of the specific node is there any methods?
Okay, as you asked me to further explain my needs and also suggested to @kapooostin to create a new issue, I'll do this now. (here is the source: #26)
So, when I create a new node/entity I wanna specify the direct parent and the package should create all the corresponding closure-table (or tree)-entries completely automatically.
That for, I had that solution:
My entities or "nodes"-table had a "parent_id"-column.
// Parent-ID
$table->integer('parent_id')->unsigned()->nullable();
$table->foreign('parent_id')->references('id')->on('nodes');
Any my corresponding model had this boot()-method:
public static function boot()
{
parent::boot();
static::created(function($model)
{
$model->createTreeEntry();
$model->save();
});
}
And this is the "createTreeEntry()"-method:
/**
* Creates all the necessary entries in the NodeTree
*/
public function createTreeEntry()
{
$tree = static::$nodeTree;
$ancestors = array_reverse($this->getAncestors());
foreach($ancestors as $ancestor)
{
$tree::create(
array(
'ancestor' => $ancestor->id,
'descendant' => $this->id,
'level' => $this->calculateLevel()
)
);
}
}
So, whenever I created a new node, I specified it's immediate parent (or null if it was a root) and then all the corresponding entries where created completely automatically.
like this:
Node::create(
'parent_id' => '7'
'description' => 'Child of node with id 7 (contact)'
);
That´s something I really find convenient and need, but I haven't yet figured out on how I would implement this into "ClosureTable 2" since you took a different approach on a few areas.
Would be great if we could find a way to implement this automatic approach.
Kindest regards,
The Dancing Bard
Code:
$category = Category::find(30);
$children = $category->descendants()->get();
Unhandled Exception
Message:
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'categories'
SQL: SELECT categories
.* FROM categories
INNER JOIN categories
ON categories
.descendant
= categories
.id
AND categories
.ancestor
<> categories
.id
WHERE parent_id
= ?
Bindings: array (
0 => 30,
)
Location:
C:\xampp\a\kat.dev\laravel\database\connection.php on line 263
Stack Trace:
#0 C:\xampp\a\kat.dev\laravel\database\connection.php(183): Laravel\Database\Connection->execute('SELECT categor...', Array) #1 C:\xampp\a\kat.dev\laravel\database\query.php(710): Laravel\Database\Connection->query('SELECT
categor...', Array)
#2 C:\xampp\a\kat.dev\laravel\database\eloquent\query.php(90): Laravel\Database\Query->get(Array)
#3 C:\xampp\a\kat.dev\application\controllers\categories.php(14): Laravel\Database\Eloquent\Query->get()
#4 [internal function]: Categories_Controller->action_index()
#5 C:\xampp\a\kat.dev\laravel\routing\controller.php(325): call_user_func_array(Array, Array)
#6 C:\xampp\a\kat.dev\laravel\routing\controller.php(285): Laravel\Routing\Controller->response('index', Array)
#7 C:\xampp\a\kat.dev\laravel\routing\controller.php(165): Laravel\Routing\Controller->execute('index', Array)
#8 C:\xampp\a\kat.dev\laravel\routing\route.php(153): Laravel\Routing\Controller::call('categories@(:1)', Array)
#9 C:\xampp\a\kat.dev\laravel\routing\route.php(124): Laravel\Routing\Route->response()
#10 C:\xampp\a\kat.dev\laravel\laravel.php(167): Laravel\Routing\Route->call()
#11 C:\xampp\a\kat.dev\public\index.php(34): require('C:\xampp\a\kat....')
#12 {main}
I was having issues with the setupReordering function.
Specifically line number 1367 if ( ! is_array($range))
if $parentIdChanged condition is false, the following is run:
if ($this->old_parent_id == $this->parent_id)
{
if ($this->position > $this->old_position)
{
$range = [$this->old_position, $this->position];
$action = 'decrement';
}
else if ($this->position < $this->old_position)
{
$range = [$this->position, $this->old_position];
$action = 'increment';
}
}
if the old parent is the same as the parent and there is no match on the if/else if section range and action are never set and throw and exception on line number 1367.
I put $range = $action = null;
at the beginning of the function and wrapped line #1315 $query->buildWherePosition($positionColumn, $range)
with:
if($action) {
$query->buildWherePosition($positionColumn, $range)
->where($this->getKeyName(), '<>', $this->getKey())
->$action($positionColumn);
}
My problems have since stopped.
I'm not sure this is the best solution, but I figured I'd bring it to your attention.
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1005 Can't create table 'DB_NAME.#sql-
3af_3d' (errno: 150) (SQL: alter table `TABLE_NAME` add constraint TABLE_NAME_parent_id_foreign foreign key (`parent_id`) references `TABLE_NAME` (`id
`))
This is the particular line that causes the issue
$table->foreign('parent_id')->references('id')->on('TABLE_NAME');
I looked into it a little and it may possible be an issue with the database engine being InnoDB.
Hi,
I think that the parent_id and real_depth columns that are part of the entities table are redundant since they can be obtained from the entities_closure table. Furthermore, they introduce chances of not being updated properly (basically, the tables are not normalized).
Let me know what is your opinion on this 😄
$ php artisan closuretable:make --entity=page
create 2014_03_26_163419_create_pages_table
create 2014_03_26_163419_create_page_closures_table
create age
create ageInterface
create ageClosure
create ageClosureInterface
The first letter from the models is omitted
When trying to add a child to a node, I get an SQL error because position is trying to be set to -1.
To reproduce, use the current master branch as of writing (e70b08c). Pseudocode:
$node = new Node;
// Set some attributes
$node->save();
$newNode = new Node;
// Set some attributes
$node->addChild($newNode);
The problem does not occur on the 3.0.3 stable branch, but I needed dev-master so that the fix for $range being undefined was included.
Hello,
I'm just wondering that there is no getAllChildren() Method to get all relations? Is there a reason for that?
regards from Austria
Hi.
When in windows we use these options , this error occurred:
[ErrorException]
file_put_contents(C:\xampp\htdocs\crm\app/workbench/rollon/access/src/migra
tions//2014_06_29_082339_create_permissions_table.php): failed to open stre
am: No such file or directory
for fix that i made these changes in franzose/closure-table/src/Franzose/console/MakeCommand.php line 152 and 153:
$this->options[$options[5][0]] = $input[5] ? $input[5] : $larapath . '/models';
$this->options[$options[6][0]] = $input[6] ? $input[6] : $larapath . '/database/migrations';
to use relative path for this. its working in Ubuntu too...
Wanted to install and try out the 3.0-dev branch, noticed that your composer.json is replacing phpseclib...
https://github.com/franzose/ClosureTable/blob/3.0-dev/composer.json#L26
Is there a particular reason for this? Just wondering....
$page = Page::create(array(
'title' => 'Test Title',
'excerpt' => 'Test Excerpt',
'content' => 'Test content'
));
ErrorException : Trying to get property of non-object
protected function getAncestor()
{
if ($this->hidden[static::ANCESTOR] === null)
{
$this->hidden[static::ANCESTOR] = $this->buildClosuretableQuery()
->where(static::DEPTH, '=', $this->getDepth())
->first()
->{static::ANCESTOR};
}
I have them a new row in table page.
We can discuss here how to implement a DatabaseSeeder for ClosureTable.
In particular, how to implement a scan of an array of nodes.
Hello folks!
If I choose to add a prefix this wonderful package gives me the following error:
[PDOException]
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'database.page_closure' doesn't exist
Yes, well it should take "database.l4_page_closure" in this case ;)
If I remove the prefix it finds the closure-table.
Kindest regards
The Dancing Bard
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.