Intereting Posts
Установка cURL в php-ошибке Определение типа Mime локального файла (Content-type) с помощью PHP preg_match, чтобы найти слово, которое заканчивается определенным символом PHP readfile (), вызывающий коррумпированные загрузки файлов Лучший способ хранения списка идентификаторов пользователей .htaccess: нет указанного входного файла Кто-нибудь когда-либо использовал PayPal Website Payments Standard с переменными SESSION? Как получить доступ к базе данных в классе библиотеки? В PHP-проекте, какие шаблоны существуют для хранения, доступа и организации вспомогательных объектов? Codeigniter с использованием базы данных доступа ms Возврат 2 дат из единого поля для запроса MYSQL db Неустранимая ошибка: использование $ this, если не в контексте объекта Лучшая стратегия для переноса mysql enums на объекты доктрины с symfony2? Получайте товары из интернет-магазина, используя простой парсер и разбиение на страницы c ++ php и статическая библиотека

Как связать модель в CakePHP по полям, не названным по соглашению?

У меня две таблицы с username поля в обоих. Как я могу указать имя поля для локальной и внешней таблицы?

Я хочу, чтобы CakePHP будет делать что-то вроде

 ON (`T1`.`username` = `T2`.`username`)` 

в результате. Без каких-либо изменений таблицы будут соединены со следующим условием:

 ON (`T1`.`id` = `T2`.`t1_id`)` 

Устанавливать 'foreign_key' = 'username' недостаточно, потому что он будет генерировать запрос следующим образом:

 ON (`t1`.`id` = `t2`.`username`)` 

У меня есть два решения. Первый использует свойство join и объединяет таблицу на лету. В таком случае я могу установить как локальное, так и внешнее поле. Но если мне нужно соединить больше таблиц с этим, связанным вручную, я больше не могу использовать содержать. Мне нужно писать следующие объединения вручную, даже если эти ассоциации были установлены правильно. Так что мне нужно писать длинные определения соединения каждый раз, вместо этого просто используйте 'contain' => array('T1', 'T2', 'T3')

Во-вторых, установить «primary_key» таблицы в соответствующее поле. Это можно сделать в файле модели или во время выполнения. В моем случае это невозможно сделать в модели, потому что эта таблица также имеет «правильную» ассоциацию по полю 'id' . Настроить его время исполнения – это случай, но мне это не нравится, потому что это не очевидно и выглядит как хак.

Когда я задаю этот вопрос, я подумал, что мне не хватает чего-то очевидного, но теперь я понимаю, что CakePHP просто не может этого сделать. Поэтому я начал щедрость, надеясь, что кто-то разделяет решение. Если нет, я попытаюсь прочитать источники торта и переопределить модель некоторого метода, чтобы добавить способность определять локальное поле рядом с 'foreign_key' в определении ассоциации.

ForeignKey false

Чтобы иметь ассоциацию, которая не использует первичный ключ соответствующей модели в условиях соединения, стандартным способом это будет использование 'foreignKey' => false .

Т.е. тогда как эта ассоциация:

 class Comment extends AppModel { public $belongsTo = array( 'Profile' => array( ) ); } 

Будет генерировать этот sql:

 SELECT ... LEFT JOIN profiles on ON (Profile.id = Comment.profile_id) 

Указание того, что foreignKey нельзя использовать так:

 class Comment extends AppModel { public $belongsTo = array( 'Profile' => array( 'foreignKey' => false ) ); } 

Будет производить этот (недопустимый) sql:

 SELECT ... LEFT JOIN profiles on ON () 

С этого момента желаемые условия могут быть заданы с помощью ключа массива условий:

 class Comment extends AppModel { public $belongsTo = array( 'Profile' => array( 'foreignKey' => false, 'conditions' => array( 'Comment.username = Profile.username' ), ) ); } 

(Обратите внимание, что условия определяются как строка), в результате чего:

  SELECT ... LEFT JOIN profiles on ON (Comment.username = Profile.username) 

Обновить:

Просто укажите, что вы не хотите использовать foreignKey, а затем укажите условия (все в пределах ассоциации:

'foreignKey' => false и 'conditions' => 'Comment.username = User.username'

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


Это очень четко определено в книге CakePHP: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasmany

 class User extends AppModel { public $hasMany = array( 'Comment' => array( 'className' => 'Comment', 'foreignKey' => 'user_id', // <---- THIS HERE you can define the foreign_key 'conditions' => array('Comment.status' => '1'), 'order' => 'Comment.created DESC', 'limit' => '5', 'dependent' => true ) ); } 

Что такое внешний ключ? :

В контексте реляционных баз данных внешний ключ является полем в одной таблице, который однозначно идентифицирует строку другой таблицы.

Просто обходной путь, который должен работать для ваших отношений hasMany, когда вы хотите получить пользователя и все его комментарии

 class User extends AppModel { public $hasMany = array( 'Comment' => array( 'finderQuery' => 'SELECT * FROM comments Comment LEFT JOIN users User ON Comment.username = User.username WHERE User.id = {__CakeID__}' ) ); } 

Надеюсь, поможет

Я боролся с этой точной проблемой в течение нескольких дней, и решение, которое я нашел (явно не рассмотренное выше): hasMany должно иметь 'foreignKey' => false а belongsTo ДОЛЖНА также иметь 'foreignKey' => false и иметь 'conditions' => 'Comment.username = User.username' . С conditions в качестве строки не ассоциировать массив. Вот так:

 // Profile public $hasMany = array( 'Comment' => array( 'foreignKey' => false, ) ); // Comment public $belongsTo = array( 'Profile' => array( 'foreignKey' => false, 'conditions' => array('Profile.username = Comment.username') ) ); 
 public $hasMany = array( 'Comment' => array( 'className' => 'T1', 'foreignKey' => 'username', 'dependent' => true ) ); 

Обратите внимание, что зависимое значение true удалит все T1, когда T2 были удалены из торта.