Здравствуйте. Я хочу сделать на своем сайте систему достижений. Каким образом лучше реализовать расчеты? У меня есть 2 варианта. 1. Просто на странице где нужно выводить достижения сделать много проверок, например: пересчитать все сообщения пользователя и если больше 50 вывести ачивку и т.д по всем достижениям. 2. В БД, в таблице users добавить несколько столбцов achiv_1, achiv_2 и тд. Затем сразу после публикации сообщения произвести расчет и если сообщений стало больше 50, то в ячейку aciv_1 ввести "1". Или же есть еще какие-то варианты как организовать такую систему?
Костылять или не костылять понятно только вам потому что только вы знаете как написана ваша система. В общем случае возможно два базовых варианта. Вариант 1. Костыльный. Вы пишите класс-обвязку ваших достижений включая метод пуша достижения пользователя. Далее проходитесь по экшенам за которые хотите выставлять достижение и делаете чтото вроде Код (Text): Achievement::push($user, 'action_name_or_id'); Вариант 2. Не костыльный. Отслеживаете к примеру крон-скриптом действия, совершаемые пользователями по базе данных (или там где вы их храните) и пишете их в структуру (таблицу) отвечающую за хранение достижений пользователей. Не внедряясь таким образом в уже написанные классы приложения.
крон это не очень хорошо - человек 51 пост сделает и будет думать, а чего это мне не дают просмотр скрытых сообщений для которых требуется 50 постов. лучше всего добавить поле\поля правил пользователю с умолчанием 0 и при каждом действии создания, например добавка репутации пользователю или добавка сообщения пользователем, возвращать из базы количество сообщений и\или репутации и уже исходя из вашего правила >50 добавлять или <50 отнимать ему в поле идентификатор уровня
это вы додумываете требования к реализации. Из заявленного в топике нет требований к реалтайму обновления достижений. Добавлено спустя 6 минут 38 секунд: С опытом приходит осознание того, что прежде чем строить небоскрёб, нужно посмотреть, а вдруг достаточно квартиру арендовать. В вашей рекомендации вы после каждого (!) экшена делаете запрос на получение общего количества сообщений, выполняете логику на какие-то там проверки и выполняете апдейт-запрос. При этом вы смело предполагаете, что есть возможность добавлять поля к объекту пользователя (либо вы поле в таблице имели ввиду, что ещё интереснее). Вот где костыль так костыль. Нельзя забывать о том, что эти отслеживаемые действия это пользовательские действия и каждое действие, в особенности апдейт таблицы в бд замедлит отработку основного действия экшена (добавление записи в блог к примеру). Правильное же решение задачи тса с кучей зависимостей уже на реализованном проекте кроется в в решении на уровне базовых классов приложения, когда при выполнении конкретного экшена конкретного контроллера с включенным параметром его отслеживания и зачета в репутацию пользователя. При этом сама операция расчета логики изменения репутации и её записи должна вестись параллельно обработке основного действия экшена и никак не прерывая его. То есть передали параметры специально обученному воркеру и забыли о нём. Правильное решение не значит верное в каждом конкретном случае. И если речь идет о каком-нибудь форуме с посещаемостью 1000 хостов в сутки то реализация логики и апдейта репутации юзера вполне можно и закостылить вызовом метода класса, дергающего в текущем потоке эту логику. В этом случае, возможно будет целесообразно для быстрой записи-чтения параметров репутации использовать хранилище типа ключ-значение.
ну все зависит от того как реализована система. и как вы ниже добавили - лучше всего когда это будет на уровне базовых классов приложения.