Проверить, все ли обязательные поля заполнены

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
yura1976
Сообщения: 134
Зарегистрирован: 2012.08.06, 13:24

Проверить, все ли обязательные поля заполнены

Сообщение yura1976 »

Есть список мероприятий. Пользователь наживает кнопку "Записаться на мероприятие" около заинтересовавшего его мероприятия. В результате должна сработать проверка, все ли обязательные поля профиля он заполнил. Если все, то записать его на мероприятие. Если есть хотя бы одно незаполненное, выдать ему сообщение "Для записи на мероприятие необходимо заполнить все обязательные данные в профиле" + ссылка на профиль. Как осуществить эту проверку?
Форма - пошаговая (4 шага), таблица в базе одна. Для каждого шага своя модель и своя форма. Поэтому может такое быть, что часть обязательных полей в таблице заполнены, а часть нет.
Я вижу 2 варианта, но не представляю как их реализовать.
1. Наверное, можно как-то перебрать либо список параметров из rules() для каждой из 4-х моделей, для которых установлено правило require, и проверить, есть ли значения для каждого из этих параметров в таблице profile (т.е., заполнил ли пользователь все эти поля).
2. Проверить для каких полей таблицы profile не установлено NULL (т.е. не может принимать NULL, значит обязательно для заполнения).
Прошу подсказать как реализовать одно из тех что я описал или подсказать более простое решение.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Проверить, все ли обязательные поля заполнены

Сообщение unknownby »

yura1976 писал(а): 2020.12.28, 13:41 Прошу подсказать как реализовать одно из тех что я описал или подсказать более простое решение.
В принципе проверять на empty() не плохое решение по второму варианту. Чем проще и понятней написан код, тем удобнее его потом поддерживать. Но лучше сделать выбор пользователя через запрос и там указать поля, чтобы были не нулевыми. Если вернется объект с пользователем, тогда у него всё заполнено, если нет, значит есть какие-то косяки в заполнении профиля. :D
yura1976
Сообщения: 134
Зарегистрирован: 2012.08.06, 13:24

Re: Проверить, все ли обязательные поля заполнены

Сообщение yura1976 »

unknownby писал(а): 2020.12.28, 14:54
yura1976 писал(а): 2020.12.28, 13:41 Прошу подсказать как реализовать одно из тех что я описал или подсказать более простое решение.
В принципе проверять на empty() не плохое решение по второму варианту. Чем проще и понятней написан код, тем удобнее его потом поддерживать. Но лучше сделать выбор пользователя через запрос и там указать поля, чтобы были не нулевыми. Если вернется объект с пользователем, тогда у него всё заполнено, если нет, значит есть какие-то косяки в заполнении профиля. :D
Возможно, я не достаточно удачно изложил вопрос, или Вы не очень внимательно прочитали, или я не понял Ваш ответ :)
Попробую прокомментировать и уточнить. Предположим у нас уже есть данные в таблице profile, которые заполнил пользователь (сейчас пока не важно, заполнил он все обязательные данные или нет). Есть страница со списком мероприятий. У каждого мероприятия есть кнопка "Записаться". Вот тут и появляется необходимость проверки, т.е., не когда пользователь заполняет профиль, а когда он записывается на мероприятие. Именно в результате нажатия на "Записаться" необходимо обращение к методу, который и проверит заполнены ли в профиле все обязательные данные. Вот я и думаю, как это проще реализовать. Данные профиля - таблица profile и 4 модели.
Аватара пользователя
proctoleha
Сообщения: 298
Зарегистрирован: 2016.07.10, 19:00

Re: Проверить, все ли обязательные поля заполнены

Сообщение proctoleha »

Вот есть у вас модель, Events, предположим. С ее помощью вы пишете мероприятия. У модели Events есть поле profile_id типа integer, внешний ключ на таблицу profile

У поля profile_id определен кастомный валидатор, предположим метод checkProfile ()

В этом методе вы получаете данные из таблицы profile: выбери мне все поля из данной таблицы как массив. После чего у каждой из 4-х моделей вызываете методы load() и validate() Подробности про метод load () в доках. Там вторым параметром передается имя формы. У вас его не будет.

Если хотя бы у одной модели метод validate() вернет false, то к полю profile_id добавляете ошибку. А уж как прописаны правила в 4-х моделях - это вообще к теме не относится. Главное, чтобы они были верными.

Можно пойти по др. пути.

Объявляем приваное поле типа boolean $profile в модели Events

В этой же модели описываем событие afterFind () - по той же логике, что выше, и если хотя бы одна из 4-х моделей не провалидировалась, то в $profile пишем false, и уже на фронте, в форме, разруливаем ситуацию. Не забываем написать геттер!

Можно не цепляться к событию afterFind () и явно описать метод setProfile (), и явно вызывать его в нужном месте. Вообщем решение за вами. Главное, что в любом случае вы должны использовать встроенные возможности yii2

В случае использования сеттера и геттера, вы прямо в форме можете проверять if (!$events->profile), то посылать пользователя по нужному вам адресу, например, на китайскую гору Кхуйам :), и не давать регаться на мероприятие
Вот за что я не люблю линукс, так это за свои кривые, временами, руки
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Проверить, все ли обязательные поля заполнены

Сообщение unknownby »

yura1976 писал(а): 2020.12.28, 16:46 Возможно, я не достаточно удачно изложил вопрос, или Вы не очень внимательно прочитали, или я не понял Ваш ответ :)
Попробую прокомментировать и уточнить. Предположим у нас уже есть данные в таблице profile, которые заполнил пользователь (сейчас пока не важно, заполнил он все обязательные данные или нет). Есть страница со списком мероприятий. У каждого мероприятия есть кнопка "Записаться". Вот тут и появляется необходимость проверки, т.е., не когда пользователь заполняет профиль, а когда он записывается на мероприятие. Именно в результате нажатия на "Записаться" необходимо обращение к методу, который и проверит заполнены ли в профиле все обязательные данные. Вот я и думаю, как это проще реализовать. Данные профиля - таблица profile и 4 модели.
Вроде всё просто.
При нажатии на кнопку "Записаться", проверяется метод, например, $model->findProfile().
Данный метод примерно такой, но запрос нужно исправить в зависимости от всех необходимых полей, которые должны быть заполнены.

Код: Выделить всё

public function findProfile()
    {
        if (($model = Profile::find()->where(['profile_id' => $this->profile_id])->one()) !== null) {
            return $model;
        } else {
            return false;
        }
    }
В первом случае, он вернет модель, во втором false, и делаем проверку

Код: Выделить всё

if($model->findProfile() !== false) {
//тут записаться
} else {
//тут ссылка на профиль
}
Дописываем в запрос все наши обязательные поля

Код: Выделить всё

->where(['and',
	['not', ['first_name' => null]],
	['not', ['second_name' => null]],
	['not', ['mobile_phone' => null]],
])
yura1976
Сообщения: 134
Зарегистрирован: 2012.08.06, 13:24

Re: Проверить, все ли обязательные поля заполнены

Сообщение yura1976 »

unknownby писал(а): 2020.12.29, 08:47
Вроде всё просто.
При нажатии на кнопку "Записаться", проверяется метод, например, $model->findProfile().
Данный метод примерно такой, но запрос нужно исправить в зависимости от всех необходимых полей, которые должны быть заполнены.

Код: Выделить всё

public function findProfile()
    {
        if (($model = Profile::find()->where(['profile_id' => $this->profile_id])->one()) !== null) {
            return $model;
        } else {
            return false;
        }
    }
В первом случае, он вернет модель, во втором false, и делаем проверку

Код: Выделить всё

if($model->findProfile() !== false) {
//тут записаться
} else {
//тут ссылка на профиль
}
Дописываем в запрос все наши обязательные поля

Код: Выделить всё

->where(['and',
	['not', ['first_name' => null]],
	['not', ['second_name' => null]],
	['not', ['mobile_phone' => null]],
])
В Вашем решении все обязательные поля нужно прописывать в запросе. У меня была мысль так сделать (вполне возможно что из-за ограничения времени так и сделаю). Но мне этот подход не нравится. Предположим, что мы захотим сделать какое-то обязательное поле необязательным или наоборот. Изменим rules() и придется еще и этот запрос помимо rules() изменять. Не критично, но тем не менее....
Я еще не изучил внимательно предыдущий ответ ( proctoleha ), там мысль интересная. Сегодня постараюсь разобраться.
Аватара пользователя
maleks
Сообщения: 1985
Зарегистрирован: 2012.12.26, 12:56

Re: Проверить, все ли обязательные поля заполнены

Сообщение maleks »

Я бы делал как proctoleha говорит по первому варианту.
У тебя просто многошаговая форма видимо без возможности вернуться на предыдущий шаг, когда нужно грузануть в форму данные из базы, сценарий update. А было бы так, то что не понятно в задаче - поднял все 4 формы, загрузил туда данные, и проверяешь их validate(), отдельные правила require нет смысла анализировать, если пользователь прошел те шаги, то значит данные валидны.
Yii2 universal module sceleton - for basic and advanced templates
Ответить