В моем приложении CakePHP 1.2.5 у меня есть модель Profile
которая принадлежит модели User
. Модель пользователя имеет поле username
, а при выполнении find()
в модели профиля я всегда хочу автоматически получить значение User.username
. Я полагаю, что имеет смысл модифицировать метод beforeFind()
моей модели модели, чтобы автоматически содержать нужное поле.
Вот что я пытался сделать:
public function beforeFind($queryData) { // determine if the username data was already requested to be included in the return data via 'User.username' or 'User' => array('username'). $hasUserData = isset($queryData['contain']) && in_array("User.{$this->User->displayField}", $queryData['contain']); $hasUserData |= isset($queryData['contain']['User']) && in_array($this->User->displayField, $queryData['contain']['User']); // request the the username data be included if it hasn't already been requested by the calling method if (!$hasUserData) { $queryData['contain']['User'][] = $this->User->displayField; } return $queryData; }
Я вижу, что значение $queryData['contain']
правильно обновляется, но данные имени пользователя не извлекаются. Я просмотрел основной код CakePHP для метода find()
, и я обнаружил, что beforeFind()
вызов beforeFind()
вызывается после всех обратных вызовов Behaviors, что означает, что Containable уже сделал то, что ему нужно было сделать со значением $queryData['contain']
прежде чем я смог его изменить.
Как я могу обойти это без взлома ядра?
Я решил это, так что вот мой ответ, если у кого-то есть такое же усложнение. Контейнерные поля не могут быть указаны в beforeFind, поскольку все методы beforeFind()
Behaviors beforeFind()
до метода beforeFind()
модели.
Поэтому мне было необходимо изменить метод find()
непосредственно на модели профиля, чтобы добавить мое настраиваемое поле для сдерживания.
public function find($conditions = null, $fields = array(), $order = null, $recursive = null) { $this->contain("{$this->User->alias}.{$this->User->displayField}"); return parent::find($conditions, $fields, $order, $recursive); }
Мэтт, я считаю, что это хорошее решение. Я использую CakePHP 2.0.4, и я собирался извлечь только данные модели пользователя.
Только для записи, настройка actAs для модели пользователя
class User extends AppModel { public $name = 'User'; public $belongsTo = array('Role'); public $actsAs = array('Containable'); ...
Затем я переопределяю метод find следующим образом:
public function find($conditions = null, $fields = array(), $order = null, $recursive = null) { $this->contain(); return parent::find($conditions, $fields, $order, $recursive); }
Или, если намеревается получить данные профиля, например:
public function find($conditions = null, $fields = array(), $order = null, $recursive = null) { $this->contain(array('Profile')); return parent::find($conditions, $fields, $order, $recursive); }