Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Обновить модель после голосования #17

Open
loveorigami opened this issue Jan 17, 2016 · 19 comments
Open

Обновить модель после голосования #17

loveorigami opened this issue Jan 17, 2016 · 19 comments

Comments

@loveorigami
Copy link

Вывожу списком статьи через ListView.
Список кешируется. Кеш обновляется, если обновилась модель.

Голосование же идет по другому сценарию.
После факта голосования запись вставляется в таблицу rating.
Затем, после следующей выборки, обновляются поля в самой модели. Это если без кеша.

С кешем у меня эти поля не обновляются, т.к. не произошло обновления самой модели.
Получается, замкнутый круг: кеш не сбросился, т.к. не обновилась модель. Рейтинг не пересчитался, т.к. модель закеширована

Почему бы не объявлять массив моделей, т.к. они есть.

    'modules' => [
        'vote' => [
            'matchingModels' => [ // matching model names with whatever unique integer ID
                'common\models\Page' => 3, // or array with 'id' key
            ],
        ],
    ],

в виджете

                <?php echo Display::widget([
                    'model_name' => $model::className(), // common\models\Page
                    //'model_name' => 'aphorism', // вместо такой записи
                    'target_id' => $model->id, // id of current element
                ]);
                ?>

поведение

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
       return [
            'class' => \chiliec\behaviors\RatingBehavior::className(),
            'model_name' => self::className(), // common\models\Page
        ];

    }

и тогда после вставки голоса в ratiing, имея готовый класс модели, запустить код, который находится в поведении RatingBehavior.

В таком случае, инвалидируется кеш, и список статей будет отображаться верно.

@loveorigami
Copy link
Author

единственное, что заметил, это Post-ом шлется название модели без слешей, как commonmodelsPage
Тогда в проверках нужно вырезать слеши в matchingModels, а при совпадении вернуть правильную модель

@chiliec
Copy link
Owner

chiliec commented Jan 18, 2016

Идея замечательная, но нужно всё хорошенько обдумать перед таким крутым изменением. Наверняка найдутся ещё какие-то подводные камни.

@loveorigami
Copy link
Author

Вот, немного похожее решение того, о чем я написал выше и в след. issue.
https://github.com/AkiraShirase/yii2-vote

@loveorigami
Copy link
Author

Ну, тут особо кардинального изменения не произошло )...
было - page, стало - common\models\Page.
В предлагаемом выше модуле модель передается через crc32
https://github.com/AkiraShirase/yii2-vote/blob/master/widgets/Vote.php#L46
Единственное, что - после сохранения модели rating, выполнить метод afterFind поведения с привязкой к передаваемой модели..

В принципе - можно сделать отдельную ветку и там все это потестить).

@chiliec
Copy link
Owner

chiliec commented Jan 18, 2016

В принципе и от настройки matchingModels тогда можно отказаться, если создать ещё одну табличку с PK и model_name и связать её с rating. Тогда вообще всё магически будет происходить. Правда существующим пользователям придётся в неё залезть чтобы настроить такие же соответствия, какие сейчас прописаны в конфиге...

@loveorigami
Copy link
Author

Можно сделать, как один из вариантов... Во многих проектах такая табличка уже есть (у меня , по крайней мере), при привязке комментариев, избранного, и тп...

Также, такой подход удобен для выборки в личном кабинете всех проголосованных записей (типа - избранного)

@chiliec
Copy link
Owner

chiliec commented Jan 21, 2016

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

@loveorigami
Copy link
Author

Я не призывал убирать эту настройку )...
Как по мне - она вполне логична и видно, к какой модели применяется голосование и с какими настройками.
Вариант в конфиге с привязкой к namespace модели намного понятнее и удобнее (знаешь, где искать)

    'modules' => [
        'vote' => [
            'matchingModels' => [ // matching model names with whatever unique integer ID
                'common\models\Page' => 3,
                'my-local-module\models\Page' => ['id'=>2, 'allow_guests'=>false],
                'vendor\chiliec\module\page\models\Page' => ['id'=>4, 'allow_guests'=>true],
            ],
        ],
    ],

намного понятнее, чем

    'modules' => [
        'vote' => [
            'matchingModels' => [ // matching model names with whatever unique integer ID
                'page1' => 3,
                'page2' => ['id'=>2, 'allow_guests'=>false],
                'page3' => ['id'=>4, 'allow_guests'=>true],
            ],
        ],
    ],

chiliec added a commit that referenced this issue Jan 23, 2016
@chiliec
Copy link
Owner

chiliec commented Jan 24, 2016

Переделал name => id на id => name в конфиге, что, как мне кажется, более логично (индексы массива). Изменения в ветке develop, я поправил документацию, можете попробовать.
Теперь можно предположить, что у нас есть имя модели и можно подумать над тем, как сбросить её кэш...

@loveorigami
Copy link
Author

посмотрел, толковое решение...
Ну раз начали переделывать ))), то можно еще в виджете вместо названия модели передать саму модель,

        'model' => $model, //*Obligatory parameter. Object for Like/Dislike.
        'primaryField' => 'id', //Name of primary key for model

а затем, после сохранения голоса, например тут
https://github.com/Chiliec/yii2-vote/blob/master/actions/VoteAction.php#L77

запустить метод записи в модель, аналогичный
https://github.com/Chiliec/yii2-vote/blob/master/behaviors/RatingBehavior.php#L38

типа

$model::afterFind();

И поскольку обновится запись, кеш у меня автоматически сбросится...

@chiliec
Copy link
Owner

chiliec commented Jan 30, 2016

Я вот всё думаю как бы поменьше действий делать для подключения. Подключение поведения уже происходит динамически, теперь хочется ещё вынести рейтинг во внешнюю таблицу. Хотелось бы формировать его на лету (ведь по сути это всё вычисляемые избыточные данные), но похоже не получится, ведь необходимо оставить возможность делать выборку с учетом рейтинга. Надо ещё подумать, возможно найдется какой-то вариант.
Кстати, а как у Вас кэширование происходит?

@loveorigami
Copy link
Author

За кеширование у меня отвечает тоже поведение.
Кеш сбрасывается по времени, или если модель обновилась.

Примерно, как тут
https://github.com/trntv/yii2-starter-kit/blob/master/common/behaviors/CacheInvalidateBehavior.php

@loveorigami
Copy link
Author

Выборку с учетом рейтинга делать надо ). У меня сортировка ListView содержит параметр "по рейтингу". А еще понадобится выборка в личном кабинете всех записей, за которые отдан голос или добавленных в избранное.

Насчет подключения - тоже не очевидно. Можно оставить как вариант через bootstrap.

Так получается, что поведение будет цепляться к каждой модели и перебирать массив моделей из конфига... А на самом деле в проекте у меня поведение нужно в 4-5 моделях из более чем 40.

Тем более, что есть уже четкие сформировавшиеся методики подключения поведений.
Если я его подключил к определенной модели, то я знаю, что это поведение делает... И в случае чего могу отключить (или заменить на другое)...

К примеру, давно хотел предложить (или сделать у себя) добавить возможность добавлять в избранное. Это тоже своего рода "голосование". Просто удобно одним виджетом вывести эти три кнопки. У себя еще на CodeIgniter я делал такой модуль
http://new.loveorigami.info/world

@chiliec
Copy link
Owner

chiliec commented Jan 31, 2016

Возможность выборки с учетом рейтинга - обязательное условие, без которого и нет смысла выносить рейтинг во внешнюю таблицу. Главное теперь понять как это сделать :neckbeard:

Естественно можно подключать и по-старинке вместо bootstrap, но так удобнее - меньше действий и можно быть уверенным, что у всех перечисленных моделей есть это поведение. И пусть оно во всех 40 моделях будет, раз уж они поддерживают голосование, оверхэд минимален.

Насчет избранного надо подумать, возможно отдельный issue создать, пока в концепции данного модуля применения не особо вижу, всё же это несколько иная функциональность.

@loveorigami
Copy link
Author

Насчет избранного надо подумать, возможно отдельный issue создать, пока в концепции данного модуля применения не особо вижу, всё же это несколько иная функциональность.

открыл issue #19 под избранное.

Там я описал функциональность - все аналогично и проще - по крайней мере я у себя так делал.
А вот когда голосуешь, всегда есть желание понравившуюся запись иметь у себя в закладках (избранном)...

@chiliec
Copy link
Owner

chiliec commented Feb 6, 2016

Примерно, как тут
https://github.com/trntv/yii2-starter-kit/blob/master/common/behaviors/CacheInvalidateBehavior.php

Ну тогда мне кажется можно добавить вот это:

$modelName = static::getModelNameById($modelId);
$model = $modelName::findOne($targetId);
$model->trigger($modelName::EVENT_AFTER_UPDATE);

после этой строчки https://github.com/Chiliec/yii2-vote/blob/develop/models/Rating.php#L189
Ну или что-нибудь вроде того. Можете PR сделать если сработает.

@loveorigami
Copy link
Author

пока не делаю, т.к. отключил кеширование при разработке и тестировании этого модуля.
При кешировании, если помните, у меня не подгружается js.
Так что сам action не будет срабатывать.

Если получится нам переделать через asset - тогда буду пробовать

@chiliec
Copy link
Owner

chiliec commented Feb 8, 2016

Если получится нам переделать через asset

Очень не хочется отказываться от переопределения методов, выполняющихся после голосования. Но, возможно, это можно сделать не из PHP, формируя js-код, а перегружая их прямо в Javascript в другом месте. Это бы решило проблему #18.

@loveorigami
Copy link
Author

Я на днях тут делал PR в ajax-modal
https://github.com/karnbrockgmbh/yii2-modal-ajax/blob/master/README.md

Так вот, там скрипт написан в виде плагина, с возможностью call-back- ов, который можно написать прямо на странице в виде

$('.voted').on('kbModalShow', function(event, data, status, xhr) {
    console.log('kbModalShow');
});

Реализуются они при помощи триггеров
https://github.com/karnbrockgmbh/yii2-modal-ajax/blob/master/assets/js/kb-modal-ajax.js#L54

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants