CakePHP Управляет возвратом find (), используя условия для глубокой ассоциации модели 2-го уровня. - PullRequest
0 голосов
/ 16 февраля 2012

Я пытался и пытался и пытался, и я не знаю, что я делаю неправильно.У меня есть простой сценарий, где у меня есть Project hasMany Tag и Tag assignTo Project.

Когда я отображаю список всех текущих проектов, я хочу показать списоктегов с каждым.Тэги извлекаются очень хорошо с отношением hasMany, как оно есть, но я хочу, чтобы условие поиска было обусловлено, когда пользователь щелкает по любому тегу, возвращая только проекты, содержащие тег, по которому щелкнули.

Я понимаю, что яя не могу манипулировать привязкой hasMany напрямую в параметре условия моей находки, и я также понимаю, что мне нужно использовать методы unbindModel () и bindModel () для настройкивременная hasOne взаимосвязь, где Project hasOne Tag .Я предположил, что мне нужно будет следовать процессу:

  • Отмена привязки Project hasMany Tag
  • Создать привязку Project hasOne Tag
  • Тогда я смог быманипулировать полем Tag.name в моей опции условий.

Вот мои отношения в файле модели Project.php:

     public $hasMany = array(
        'Link' => array(
            'className' => 'Link',
            'foreignKey' => 'project_id',
            'dependent' => false,
        ),
        'Pledge' => array(
            'className' => 'Pledge',
            'foreignKey' => 'project_id',
            'dependent' => false,
        ),
        'ProjectPost' => array(
            'className' => 'ProjectPost',
            'foreignKey' => 'project_id',
            'dependent' => false,
        ),
        'Tag' => array(
            'className' => 'Tag',
            'foreignKey' => 'project_id',
            'dependent' => false,
        )
    );

Затем в моем файле модели Tag.php:

public $belongsTo = array(
    'Project' => array(
        'className' => 'Project',
        'foreignKey' => 'project_id',
    )
);

Все модели используют сдерживаемое поведение.Теперь внутри моего файла ProjectsController.php я изменяю привязки для достижения отношения hasOne, чтобы можно было манипулировать результатами на основе значения Tag.name:

// Я отменяю привязку отношения тега hasMany $ this-> Project-> unbindModel (array ('hasMany' => array ('Tag')));

    // I am setting up a hasOne relationship where Project hasOne Tag
    $this->Project->bindModel(array(
    'hasOne' => array(
        'MyTag' => array(
            'className' => 'Tag',
            'foreignKey' => false,
            'conditions' => array('MyTag.project_id = Project.id')
        )
    )
    ));

Затем я ввожу простую команду поиска (пока нет тегов для фильтра):

$projects = $this->Project->find(
        'all',
            array(
                'contain' => array(
                    'MyTag',
                    'User.id'
                ),
                //'conditions' => $filters ? $filters : NULL,
                'fields' => array(
                    'Project.id', 'Project.name', 'Project.description' 
                ),
            )
        );

Теперь у меня есть только ОДНА запись проекта в базе данных, но у нее есть пять тегов.Происходит то, что он возвращает ОДИН проект, но 5 раз, вот pr () результата:

Array
(
    [0] => Array
        (
            [Project] => Array
                (
                    [id] => 1
                    [name] => Test Project 01
                    [description] => Donec enim lacus
                )

            [User] => Array
                (
                    [id] => 1
                )

        )

    [1] => Array
        (
            [Project] => Array
                (
                    [id] => 1
                    [name] => Test Project 01
                    [description] => Donec enim lacus
                )

            [User] => Array
                (
                    [id] => 1
                )

        )

    [2] => Array
        (
            [Project] => Array
                (
                    [id] => 1
                    [name] => Test Project 01
                    [description] => Donec enim lacus
                )

            [User] => Array
                (
                    [id] => 1
                )

        )

    [3] => Array
        (
            [Project] => Array
                (
                    [id] => 1
                    [name] => Test Project 01
                    [description] => Donec enim lacus
                )

            [User] => Array
                (
                    [id] => 1
                )

        )

    [4] => Array
        (
            [Project] => Array
                (
                    [id] => 1
                    [name] => Test Project 01
                    [description] => Donec enim lacus
                )

            [User] => Array
                (
                    [id] => 1
                )

        )

)

Самое странное, что если я действительно включу фильтр на Поле MyTag.name (обратите внимание, я использую MyTag , потому что я изменил имя класса во время привязки), оно работает как положено:

$projects = $this->Project->find(
        'all',
            array(
                'contain' => array(
                    'MyTag',
                    'User.id'
                ),
                'conditions' => array('MyTag.name' => 'NGO'),
                'fields' => array(
                    'Project.id', 'Project.name', 'Project.description' 
                ),
            )
        );

Выше приведено толькоединственный результат. Что происходит? Как я могу предотвратить это дублирование при начальной (нефильтрованной) загрузке?

Заранее спасибо.

1 Ответ

0 голосов
/ 16 февраля 2012

Я думаю, вы должны взглянуть на hasAndBelongsToMany отношений Вот как я настраиваю поведение тега. Удачи!

EDIT

Вы могли бы сделать

$this->Project->find('first', array(
    'conditions' => array('Project.id' => $projectId),
    'recursive' => 1
));

// returns
Array [
    Project => Array [...],
    Tag => Array [all associated tags]
]

И

$this->Project->Tag->find('first', array(
    'conditions' => array('Tag.id' => $tagId),
    'recursive' => 1
));

// returns
Array [
    Tag => Array [...],
    Project => Array [all associated projects]
]

Разве это не то, что вы хотите?

...