0

I'll be straightforward: I want to manage multiple (Link) trees according to their respective menu_id. As long as there is only one tree: no problem. Things get messed up when I start another tree in my link model with a different menu id.

I whish to be able to add, edit, remove, moveUp or moveDown while preserving the scope (menu_id). This part of the documentation is unclear to me : http://api.cakephp.org/2.5/source-class-TreeBehavior.html#41-49

Here my Link model.

<?php
App::uses('AppModel', 'Model');

class Link extends AppModel {

    public $name = 'Link';

    public $displayField = 'title';

    public $actsAs = array('Tree' => array(
        'parent' => 'parent_id',
        'left' => 'lft',
        'right' => 'rght',
        'scope' => "WHAT-SHOULD-I-PLACE-HERE??",
    ));

    public $belongsTo = array(
        'Menu' => array(
            'className' => 'Menu',
            'foreignKey' => 'menu_id',
        )
    );
}

And my Menu model.

<?php
App::uses('AppModel', 'Model');

class Menu extends AppModel {

    public $displayField = 'title';

    public $hasMany = array(
        'Link' => array(
            'className' => 'Link',
            'foreignKey' => 'menu_id',
            'dependent' => false,
        )
    );

}
  • 1
    "I whish to be able to add, edit, remove, moveUp or moveDown while preserving the scope (menu_id)" - Can you give an example of unexpected result (data + operation = result != expected result)? – Wojciech Mleczek Sep 28 '14 at 21:03

2 Answers2

2

Thanks to BadHorsie I finally came up to understand that is it pointless to declare the scope in the model's behavior settings.

Instead you (currently I) need to attach the behavior on the fly, with the required scope before any action (add, edit, move up, move down etc) for this to work.

Now, what I need to make sure is that a link always has a menu_id. And when someone edits a link, the parent_id dropdown must be repopulated according to the menu_id dropdown (javascript needed here and more validation rules in the model to ensure integrity).

The solution was to create a new function in the Link model. it's goal is to preserve the scope when any modification is made to the tree (move up, move down, remove from tree, delete, etc).

public function preserveScope($menuId) {
    $this->Behaviors->attach('Tree', array(
        'scope' => array(
            'Link.menu_id' => $menuId
        ),
    ));
    return true;
}
1

The scope is basically a SQL condition (in Cake format).

So you probably need to set the scope to the menu ID that you want.

'scope' => array(
    'Link.menu_id' => 5
);

However, you probably don't know which ID yet when trying to set up the array on the class definition, so you might have to do it on the fly.

$this->Link->Behaviors->attach('Tree', array(
    'scope' => array(
        'Link.menu_id' => $id  // You need to decide how to get this ID
    ),
));

I don't know when you would need to do this though. It's up to you to decide when to attach the behavior.

Edit: If the moveUp/moveDown methods are not working correctly, perhaps the scope field you are using is not correct?

BadHorsie
  • 14,135
  • 30
  • 117
  • 191