У меня есть код, работающий с моделями, связанными с поиском, с использованием плагина поиска, но это заставляет меня сломать структуру моих модельных ассоциаций. В результате мои функции сохранения и редактирования не работают должным образом.
Вот структура моих данных.
Модель:
public $belongsTo = array(
'Movie' => array(
'className' => 'Movie',
'foreignKey' => 'movie_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'MovieStarRecurrance' => array(
'className' => 'MovieStarRecurrance',
'foreignKey' => 'movie_star_recurrance_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'MovieStarType' => array(
'className' => 'MovieStarType',
'foreignKey' => 'movie_star_type_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
public $hasMany = array(
'MovieStarLine' => array(
'className' => 'MovieStarLine',
'foreignKey' => 'movie_star_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => 'status_date',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
);
Я ищу и фильтрую в связанной модели Movie и пользователя, которому принадлежит Movie.
public $filterArgs = array(
'parent_user_id' => array('type' => 'like', 'field' => 'User.parent_user_id'),
'initials' => array('type' => 'value', 'field' => 'User.id'),
'trace' => array('type' => 'like', 'field' => 'MovieStar.trace'),
'movie' => array('type' => 'query', 'method' => 'orConditionsMovie'),
'star_type' => array('type' => 'value', 'field' => 'MovieStar.movie_star_type_id'),
'code' => array('type' => 'value', 'field' => 'MovieStar.code'),
'status' => array('type' => 'value', 'field' => 'MovieStarLine.movie_star_status_id'),
'open' => array('type' => 'value', 'field' => 'MovieStar.open'),
'from_date' => array('type' => 'query', 'method' => 'orConditionsFromDate'),
'end_date' => array('type' => 'query', 'method' => 'orConditionsEndDate'),
);
Чтобы получить доступ к этим моделям на верхнем уровне моего поиска, я отвязываю ассоциацию модели Movie createdTo и повторно связываю ее как hasOne. Я делаю то же самое для MovieStarLine и MovieStarStatus.
Контроллер:
$this->MovieStar->recursive = 0;
$this->MovieStar->unbindModel( array(
'belongsTo' => array('Movie')
)
);
// MovieStarStatus to be top level json element
$this->MovieStar->bindModel( array(
'hasOne' => array(
'Movie' => array(
'foreignKey' => false,
'conditions' => array('Movie.id = MovieStar.movie_id'),
'fields' => array('Movie.id', 'Movie.movie_id', 'Movie.user_id', 'Movie.movie_mid', 'Movie.movie_dba')
),
'User' => array(
'foreignKey' => false,
'conditions' => array('Movie.user_id = User.id'),
'fields' => array('User.id', 'User.initials', 'User.user_first_name', 'User.user_last_name', 'User.name', 'User.parent_user_id', 'User.secondary_parent_user_id')
),
'MovieStarLine' => array(
'foreignKey' => false,
'conditions' => array('MovieStarLine.movie_star_id = MovieStar.id',
'MovieStarLine.id = (SELECT id FROM "public"."movie_star_lines" AS "MovieStarLine" WHERE movie_star_id = MovieStar.id ORDER BY status_date DESC NULLS LAST, id DESC LIMIT 1)' // Get only most recent line
),
'order' => array( 'MovieStarLine.status_date' => 'DESC NULLS LAST')
),
'MovieStarStatus' => array(
'foreignKey' => false,
'conditions' => array('MovieStarLine.movie_star_status_id = MovieStarStatus.id'),
),
),
));
$this->MovieStar->contain(array(
'Movie',
'MovieStarLine' => array('MovieStarStatus'),
'MovieStarType',
'MovieStarRecurrance',
'User',
'MovieStarStatus'
));
// This is where the search filter occurs
$this->Prg->commonProcess();
$this->paginate = array( 'conditions' => $this->MovieStar->parseCriteria($this->Prg->parsedParams()), 'limit' => 100);
$movieStars = $this->paginate();
$this->set(compact('movieStars'));
}
Проблема в том, что когда я пытаюсь выполнить поиск по parent_user_id или инициалам, я получаю ОШИБКУ: отсутствует запись FROM-предложения для таблицы «Пользователь».
Похоже, динамическая привязка не работает. Мне нужно удалить фильм из принадлежности
Модель:
public $belongsTo = array(
//'Movie' => array(
// 'className' => 'Movie',
// 'foreignKey' => 'movie_id',
// 'conditions' => '',
// 'fields' => '',
// 'order' => ''
//),
'MovieStarRecurrance' => array(
'className' => 'MovieStarRecurrance',
'foreignKey' => 'movie_star_recurrance_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'MovieStarType' => array(
'className' => 'MovieStarType',
'foreignKey' => 'movie_star_type_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
и добавьте hasOne для фильмов и пользователей, чтобы поиск работал.
public $hasOne = array(
'Movie' => array(
'foreignKey' => false,
'conditions' => array('Movie.id = MovieStar.movie_id'),
'fields' => array('Movie.id', 'Movie.movie_id', 'Movie.user_id', 'Movie.movie_mid', 'Movie.movie_dba')
),
'User' => array(
'foreignKey' => false,
'conditions' => array('Movie.user_id = User.id'),
'fields' => array('User.id', 'User.initials', 'User.user_first_name', 'User.user_last_name', 'User.name', 'User.parent_user_id', 'User.secondary_parent_user_id')
),
'MovieStarLine' => array(
'foreignKey' => false,
'conditions' => array('MovieStarLine.movie_star_id = MovieStar.id',
'MovieStarLine.id = (SELECT id FROM "public"."movie_star_lines" AS "MovieStarLine" WHERE movie_star_id = MovieStar.id ORDER BY status_date DESC NULLS LAST, id DESC LIMIT 1)' // Get only most recent line
),
//'order' => array( 'MovieStarLine.status_date' => 'DESC NULLS LAST')
),
);
Я не могу этого сделать, потому что это нарушает все мои функции сохранения и редактирования. Кто-нибудь знает, как правильно перебиндить ассоциации?
##################### UPDATEЯ нашел частичное решение, которое, по-видимому, избавляет меня от того, что модель пользователя не отображается.
«Передача false в качестве второго параметра вашего вызова Model::bindModel. Это сделает вашу привязку «на лету» продолжительностью запроса». из этого ответа.
Возможно, это исправило мои привязки, но я все еще не уверен, потому что теперь у меня есть ошибка с подсчетом и группировкой.
ОШИБКА: столбец «MovieStarLine.status_date» должен отображаться в предложении GROUP BY или использоваться в совокупности
SQL-запрос: SELECT COUNT(*) AS "count"
$this->MovieStar->unbindModel( array(
'belongsTo' => array('Movie')
), false
);
// MovieStarStatus to be top level json element
$this->MovieStar->bindModel( array(
'hasOne' => array(
'Movie' => array(
'foreignKey' => false,
'conditions' => array('Movie.id = MovieStar.movie_id'),
'fields' => array('Movie.id', 'Movie.movie_id', 'Movie.user_id', 'Movie.movie_mid', 'Movie.movie_dba')
),
'User' => array(
'foreignKey' => false,
'conditions' => array('Movie.user_id = User.id'),
'fields' => array('User.id', 'User.initials', 'User.user_first_name', 'User.user_last_name', 'User.name', 'User.parent_user_id', 'User.secondary_parent_user_id')
),
'MovieStarLine' => array(
'foreignKey' => false,
'conditions' => array('MovieStarLine.movie_star_id = MovieStar.id',
'MovieStarLine.id = (SELECT id FROM "public"."movie_star_lines" AS "MovieStarLine" WHERE movie_star_id = MovieStar.id ORDER BY status_date DESC NULLS LAST, id DESC LIMIT 1)' // Get only most recent line
),
'order' => array( 'MovieStarLine.status_date' => 'DESC NULLS LAST')
),
'MovieStarStatus' => array(
'foreignKey' => false,
'conditions' => array('MovieStarLine.movie_star_status_id = MovieStarStatus.id'),
),
),
), false);