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
Конфигурация модели #4078
Comments
Нужен конкретный пример конкретной задачи, которую вы пытаетесь решить. Т.к. это
Пахнет нарушением MVC. Скорее всего у задачи есть более правильный путь решения, без внесения каких либо изменений в фреймворк. |
к примеру у меня есть модуль Like, и я хочу на основе его сделать blacklist и whitelist а так же favorites, и хочу конфигурировать, к примеру имя таблицы в которой это будет храниться. 3 вышеописанных модуля не предел, под эту логику с 10 точно можно найти применение, а с моим вариантом и без писанины кода, а просто разруливая конфигами у 1 модуля |
Вы хотите динамически менять название таблицы в конкретной модели? |
ну это как пример, не нравится имя, давайте пусть будет задать конкретное регулярное выражение для валидатора или же какойто класс для связи, в одном случае у меня будет связь на пользователей, в другом на книжки (т.е 1 случай пользователь заносит в список, во втором случае "я читал" |
У меня складывается ощущение, что вы хотите 3 различные модели уместить в одной. Это конечно может быть заманчиво и казаться "умным" ходом, но в целом это bad practice. |
специально ничего не искал, в поиске вбил yii2-user, первые 3 вариант:
|
практика плохая, но юзают поголовно все, любое расширение покажите кто не вызывает в моделе модуль |
В модели можно определять виртуальные атрибуты и передавать любые данные посредством их использования. |
собственно все началось с обсуждения на русскоязычном канале когда то вот такого подхода - https://github.com/artkost/yii2-qa/blob/master/ActiveRecord.php#L25 и было предложено проанализировать, что если 2 модуля подключены одинаковых, но с разными конфигами |
а как быть с зависимыми моделями? hasOne, к примеру |
👍 Если честно то сложно придумать, что то более отвратительное, чем это. |
я начал городить сначала, что у модуля свой контейнер di и он не статический (т.к. статический бы не решил проблему), но все уперлось в и юзать чтото типа $module->createObject($ModelClass) и там бы в конструктор и падал модуль |
собственно, если уж и быть откровенным, то я хочу в модель передавать ничто иное как id module- ну думаю это уже понятно :) |
кстати идея с изолированными контейнерами у модуля, тоже имела бы право на жизнь, но как выше сказано |
Решается заведением в модели свойства static $tableName и передачей в него нужной информации (извне).
Решается либо заведением свойства |
передача нужной информации не будет работать со связанными моделями или мне каждый раз когда я вытаскиваю связанную модель передавать в нее модуль через статику? |
опять же статика не решит проблему 1 модель - несколько модулей |
можно конечно статику засунуть в трейт, ведь статика в трейте локальна для объекта, но опять же костыли |
Передавать модуль в модель не нужно, это аналогично тому что вы передадите в модель контроллер или виды. ПОЛНОЕ нарушение MVC парадигмы. Нужно передавать конкретные данные необходимые для работы модели.
Shared модель для нескольких модулей это УЖЕ плохая идея сама по себе. Как вариант вместо статики можно пойти радикальным путем и генерировать модель в нужным tableName() один раз в соответствии с каким то шаблоном и настройками. Такая модель будет и быстрее и проще. |
хорошо, передавать модуль в модель плохая идея, но как конфигурировать модель? почему модель изолированна от внешних параметров? как быть если я хочу передать какойто параметр в релатед модель и этот параметр должен повлиять на инициализацию? Я и хочу передать модуль в модель как объект для конфигурации модели. Пусть это будет не модуль (раз нарушает парадигмы), а аля ConfigureObject |
Это отдельный вопрос и над ним нужно подумать... В целом |
интереснее я ничего не придумал :) ну, если не против пусть повисит пока открытым, может поддтянется народ к обсуждению |
@lynicidn А вообще собственно в чем проблема? public static function instantiate($row)
{
return new static( //передавайте что хотите, можно использовать $this->... );
} |
$this это не статика а текущий инстанс объекта, но не суть.
Мы же вели речь о проблемах передачи данных в related модели. Как это относится к этой теме? На текущий момент public static function instantiate($row)
{
return new static($this->config);
} например. Непонятна необходимость наличия $config в сигнатуре этого метода. |
@lynicidn Сорри, не обратил внимания что метод статический ) |
@lynicidn Вероятно тут более рационально просто сделать метод нестатическим (не уверен). Т.к. даже если сделать |
не статическим не получится, т.к. в query передается called class, я предлагаю к нему еще добавлять конфиг |
сейчас набросаю коммит, для наглядности, что поменяется и как это скажется на BC |
Забавно: создание динамических таблиц и нарушение принципов Active Record вы считаете нормальным, а дифференциацию данных по значению поля - не правильным. |
динамическую таблицу не получится, т.к. |
выход есть всегда - расширить модель и перекрыть события новыми - согласен. Лишняя модель, т.е. возьми расширение и еще расширяй |
2 пример - 1 модель, 1 логика, работает с SenderInterface, но я хочу чтобы 1 модель отправляла смс уведомления, а другая email |
|
т.е. со связями работать так? : foreach ($group->getUsers() as $user) {
$user->messageStrategy = 'email';
$user->send();
} |
против: $this->hasMany(['class' => User, 'messageStrategy' => 'email'], ....) |
Думаю причина не приятия вами моих аргументов проста: вы создали решение, нарушив базовые принципы MVC, позволив модели напрямую взаимодействовать с модулем и забирать оттуда данные и параметры. Когда вы пришли к задаче подключения одного и того же модуля дважды, вместо того чтобы переосмыслить подход, вы ищете "костыль" который позволил бы вам все не переделывать. |
а разве модуль не подразумевает многократное использование? или же не более 1 раза в приложении? |
Раз уж дошло до этого, то вероятно сам метод "send()" следует разместить в модуле (или его компоненте) а не в модели, тогда код будет выглядеть следующим образом:
|
Это зависит от его реализации. Если вы хотите чтобы модуль можно было использовать дважды, то вы должны об этом позаботиться при его разработке. |
первый пример еще опишите, как бы вы решили и я отстаю |
это какой? |
пример: мне надо по разному отреагировать на инициализацию модели, в зависимости от модуля которому она "принадлежит" |
уменьшу - вообще как я могу задать логику модели для инициализации? |
Например?
Конкретнее какие действия вы хотите произвести при инициализации модели? В чем их необходимость? |
Мы с @lynicidn обсудим его задачи в Skype. Пока тикет ценности не несёт, формулировка задачи слишком расплывчатая. Закрываю. Если действительно будет задачка подходящая, я помогу оформить более чёткое описание. |
@klimov-paul какой вариант ты считаешь правильным для конфигурирования имени класса и пк аттрибута у связанной модели, т.е. модуль каменты - модель Comment function getUser()
{
$this->hasOne(/*вот тут как сделать универсально, чтобы модуль можно было подключить без изменения кода модели*/)
} |
а класс какой указывать? |
User class |
Я вижу ты все еще не слушаешь. |
извини за тупость, но ткни плиз |
как вариант делать $model->getUser($userModule) |
если я связываю 2 модуля они не должны знать друг о друге явно и это должно конфигурироваться, разве нет? |
в симфони продуманнее, через интерфейс и маппинг :( там связать бандлы можно |
В данной реализации фреймворка невозможно никак сконфигурировать модель, т.к. все упирается на
public static function instantiate($row)
. Хотелось, чтобы разработчики пересмотрели свое мнение касательно данного нюанса, и все таки дали разработчикам возможность задавать конфиг по умолчанию. На самом деле сложного здесь не очень много, но не хотелось бы создавать свои грабли. Для начала опишу случаи когда это может понадобиться - к примеру мы используем 1 модуль в нескольких местах и хотим чтобы наша модель в зависимости от конфигурации модуля реализовывала то или иное поведение. Как второй вариант задача сценария для релатед моделей. Собственно хотелось бы предложить вActiveQueryTrait
заменить modelClass на modelConfig и разрешить делать следующие 3 пункта:$this->hasMany(['class'=>'ModelClass', 'property' => $var], ....)
hasOne
ModelClass::find(['property' => $var])
далее изменим вышеупомянутую функцию
instantiate($row, $config = [])
Данное решение полностью удовлетворяет обратной совместимости и многие разработчики думаю будут рады этому введению, т.к. сейчас смотря на расширения кто на что горазд в передаче того же модуля в модель.
The text was updated successfully, but these errors were encountered: