У меня есть таблица проектов и таблица Users, которые связаны отношением HABTM. На странице «Добавить» нового проекта у меня есть несколько флажков, чтобы выбрать «Пользователи для нового проекта». Я хочу иметь хотя бы одного пользователя для проекта. Каков наилучший способ приблизиться к этому в CakePHP?Проверка формы HABTM в CakePHP
ответ
Попробуйте это:
// app/models/project.php
/**
* An additional validation check to ensure at least one User is
* selected. Spoofs Cake into thinking that there are validation
* errors on the Project model by invalidating a non-existent field
* on the Project model, then also invalidates the habtm field as
* well, so when the form is re-displayed, the error is displayed
* on the User field.
**/
function beforeValidate() {
if (!isset($this->data['User']['User'])
|| empty($this->data['User']['User'])) {
$this->invalidate('non_existent_field'); // fake validation error on Project
$this->User->invalidate('User', 'Please select at least one user');
}
return true;
}
Блог teknoid имеет довольно глубокое решение вашей проблемы здесь. Самый простой способ сделать это - добавить пользовательскую проверку в вашу модель, как вы упомянули в своем комментарии выше. Проверьте http://teknoid.wordpress.com/2008/10/16/how-to-validate-habtm-data/
Из статьи, где Tag HABTM Post (:: Проект HABTM Пользователи):
Во-первых, мы утверждаем модель тегов, с помощью , используя данные из формы, чтобы гарантировать, что в был выбран хотя бы один тег. Если так, мы сохраняем сообщение и соответствующие теги.
Я просто смотрел на свою проблему сам по проекту и наткнулся на несколько более элегантное решение, до тех пор, пока вы только имеете дело с отношения HABTM и вам нужно убедиться, что выбран хотя бы один флажок.
так, например, вы редактируете проект, и вы хотите, чтобы это было связано с, по меньшей мере, один пользователь
Добавить это beforeValidate()
// проверить HABTM модель и добавить к данным
foreach($this->hasAndBelongsToMany as $k=>$v) {
if(isset($this->data[$k][$k]))
{
$this->data[$this->alias][$k] = $this->data[$k][$k];
}
}
В правилах проверки добавьте следующее:
'User' => array(
'rule' => array('multiple', array('min' => 1)),
'message' => 'Please select one or more users'
)
Это работает по большей части, но div, содержащий ошибку, не появляется. Есть идеи? – Joseph
I-й пошатнулся по той же проблеме, но теперь - через 3 года - с CakePHP 2.3.
Должно быть ясно; Group
имеет и принадлежит User
. Я имел форму, как это:
// View/Groups/add.ctp
echo $this->Form->input('name');
echo $this->Form->input('User');
С правила проверки, как в ответ user448164 в:
// Model/Group.php
public $validate = array(
'User' => array(
'rule' => array('multiple', array('min' => 1)),
'message' => 'Please select one or more users'
)
);
Это не сработало, после погуглить его, я нашел этот вопрос, который не мог» t остается лучшим решением. Тогда я попробовал несколько вещей, и обнаружил, что это работает просто отлично:
// View/Groups/add.ctp
echo $this->Form->input('name');
echo $this->Form->input('Group.User');
Слишком простое решение, но пришлось копаться в ней, чтобы узнать, что это работает таким образом.
Надеюсь, кому-то это поможет.
Обновление для CakePHP 2.4.x (возможно, 2.3.x, а)
Когда я писал этот ответ, я использовал CakePHP 2.3.х. В то время он отлично работал для проверки и сохранения данных.Теперь, применяя тот же код в новом проекте, используя CakePHP 2.4.x, он больше не работает.
Я создал тестовый пример, используя следующий код:
$data = array(
'User' => array(
'Client' => array(8)
),
);
$this->User->create();
$this->User->saveAll($data);
Моя первая мысль была: Сохранение всех спасательных средств все модели «корень», что на самом деле имеет смысл для меня. Чтобы сохранить глубже, чем просто «корневые», вам нужно добавить опцию deep
. Итак, у меня закончился следующий код:
$data = array(
'User' => array(
'Client' => array(8)
),
);
$this->User->create();
$this->User->saveAll($data, array('deep' => true));
Работает как очарование! Счастливое кодирование. :)
Обновление (2014/03/06)
снова Борьба с той же проблемой, в данном случае с hasMany
вместо habtm
. Похоже, он ведет себя одинаково. Но я снова нашел этот ответ и смутился.
Я хотел бы уточнить, что это ключ к использованию Group.User
вместо User
на вашем входе. Иначе он не будет использовать проверку модели User
.
Это правильный ответ для Cake 2.3 – Steven
Я сделал это изменение для моего кода для аналогичной проблемы. Валидация работает правильно, но таблица базы данных, связанная с помощью HABTM, больше не автоматически сохраняет новые данные. Чего не хватает? – Blazemonger
@Blazemonger Когда я написал его, он отлично работал как для проверки, так и для сохранения. Но как-то он сломан в последней версии CakePHP. Давайте сделаем еще больше копания ... --- См. Обновление ответа для получения дополнительной информации! –
Если вы используете CakePHP 2.3.x, возможно, потребуется добавить этот код в вашей модели в дополнение к коду, который GuidoH при условии, в противном случае ваши данные HABTM модель не может сохранить:
public function beforeSave($options = array()){
foreach (array_keys($this->hasAndBelongsToMany) as $model){
if(isset($this->data[$this->name][$model])){
$this->data[$model][$model] = $this->data[$this->name][$model];
unset($this->data[$this->name][$model]);
}
}
return true;
}
Согласно моему комментарию к ответу Guido выше, я использую ответ Guido точно, однако я изменяю данные с обратным вызовом beforeSave, прежде чем он сохраняет базу данных.
У меня есть этот вопрос на торт 2.4.5+
public function beforeSave($options = array()) {
$temp = $this->data['Group']['User'];
unset($this->data['Group']['User']);
$this->data['User']['User'] = $temp;
return true;
}
2016 обновление для CakePHP 2.7
Полный ответ здесь: HABTM form validation with CakePHP 2.x
TL; DR;
AppModel.php
public function beforeValidate($options = array()){
foreach (array_keys($this->hasAndBelongsToMany) as $model){
if(isset($this->data[$model][$model]))
$this->data[$this->name][$model] = $this->data[$model][$model];
}
return true;
}
public function afterValidate($options = array()){
foreach (array_keys($this->hasAndBelongsToMany) as $model){
unset($this->data[$this->name][$model]);
if(isset($this->validationErrors[$model]))
$this->$model->validationErrors[$model] = $this->validationErrors[$model];
}
return true;
}
В основной модели вашего HABTM:
public $validate = array(
'Tag' => array(
'rule' => array('multiple', array('min' => 1)),
'required' => true,
'message' => 'Please select at least one Tag for this Post.'
)
);
- 1. Проверка формы HABTM с помощью CakePHP 2.x
- 2. CakePHP формы помощника - HABTM множественного флажка стайлинг
- 3. CakePHP сохранение данных HABTM
- 4. Проверка правильности формы JQuery и проверка CakePHP
- 5. Cakephp 1.3 HABTM Результаты
- 6. CakePHP HABTM question
- 7. CakePHP HABTM проблема связи
- 8. CakePHP HABTM состояние
- 9. cakephp отношение habtm состояние
- 10. CakePHP HABTM отношение
- 11. CakePHP найти HABTM
- 12. HABTM with join Cakephp
- 13. Cakephp habtm save data
- 14. CakePHP display HABTM ассоциации
- 15. CakePHP HABTM делеция
- 16. CakePHP HABTM глубокие условия
- 17. Cakephp, HABTM ассоциация
- 18. CakePHP - HABTM или hasMany
- 19. CakePHP добавить несколько HABTM
- 20. CakePHP: HABTM Несколько раз
- 21. CakePHP HABTM relations listing
- 22. CakePHP постраничной несколько HABTM
- 23. Cakephp HABTM save -.-
- 24. cakephp HABTM association saveAll?
- 25. CakePHP - Сохранение HABTM
- 26. CakePHP данные извлечения HABTM
- 27. CakePHP: HABTM отношение
- 28. CakePHP HABTM отношения
- 29. Найти с HABTM в cakephp
- 30. UpdateAll и HABTM в CakePHP
Отлично! Спасибо Нейлу. – Sabourinov
Это работает, чтобы проверить, но когда страница перезагружается, я потерял некоторые данные и получаю ошибки из-за отсутствия данных. Есть предположения? – Dave