• Как испраить ошибку: SQLSTATE: Duplicate alias: имя таблицы указано больше одного раза?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Пожалуйста, называйте связи так, как называется модель, которую вы хотите получить.

    items() ? чего? вы хотите получить CartProduct. назовите cartProducts()

    очень редко, но бывает, когда CartProduct можно получить двумя способами. Тогда cartProductsByModel1(), cartProductsByModel2()

    исключение - абстрактные паттерны, деревья. там можно назвать parent/children/treeParent/treeChild

    <?php
    
    Class Cart {
        // ...
    
        // вот здесь написано, что CartProduct может быть одновременно в двух и более корзинах. не могу представить себе логику, где участник заказывает на сайте товар, а потом этот же товар (который ты заморозил только что) кто-то еще заказывает
        public function items(): BelongsToMany
        {
            return $this->belongsToMany(CartProduct::class, 'cart_products');
            
            // Cart.hasMany(CartProduct) + CartProduct.belongsTo(Cart) + CartProduct.belongsTo(Product)
            // и второе
            // https://github.com/illuminate/database/blob/master/Eloquent/Concerns/HasRelationships.php#L477
            // первым параметром "тип", вторым - "через что". Вы указываете, что "связь много ко многим" должна вернуть "связь много ко многим"
            // при связи Много-Ко-Многим надо Cart.belongsToMany(Product::class, 'cart_products')
        }
    }


    <?php
    
    class CartProduct {
        // ...
    
        // здесь написано, что CartProduct старше чем Product. Это выразится в том, что вы сможете "привязать" CartProduct только из самого Product, причем один раз. Это дважды неверно.
        public function product(): HasOne
        {
            return $this->hasOne(ProductVariant::class, 'id');
    
            // Во первых каждый продукт с его количеством может быть куплен много раз, а вариант всего лишь показывает на его подвид
            // Во вторых модель CartProduct создается позже чем Product, а значит писать $product.addChild($cartProduct) это снова дичь
            // Product.hasMany(ProductVariant::class) + CartProduct.belongsTo(ProductVariant::class) + $cartProduct.associate($productVariant);
        }
    
        // то же самое. CartProduct старше чем Cart, хотя он в ней лежит. BelongsTo задает старшинство и позволяет добавлять родителя в потомок, а hasOne указывает связь, которая нужна только для select, но не годится для insert
        // Потому что hasOne() - это возможность добавить потомка, причем в Eloquent нету метода addChild() его ещё и самому писать надо типа CartProduct.cart().insert($array) и это тут же нарушает идею отложенной записи, т.к. выполняет запрос немедленно и требует транзакции прямо в модели, тогда как транзакция относится к задаче, а не к модели
        public function cart(): HasOne
        {
            return $this->hasOne(Cart::class);
        }
    }
    Ответ написан
    Комментировать
  • Как испраить ошибку: SQLSTATE: Duplicate alias: имя таблицы указано больше одного раза?

    iMedved2009
    @iMedved2009
    Не люблю людей
    Это лажа
    public function items(): BelongsToMany
        {
            return $this->belongsToMany(CartProduct::class, 'cart_products');
        }

    Вы классу CartProduct прописываете отношение к самому CartProduct

    Наверное должно быть так?
    public function items(): BelongsToMany
        {
            return $this->belongsToMany(ProductVariant::class, 'cart_products');
        }
    Ответ написан
    Комментировать
  • Какую валидацию правильно делать для email в формах авторизации на js?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Во фронтенде практически не существует стандартов. В любом его направлении.
    Даже валидная вёрстка не стандарт (ну или, как минимум, не обязательный/не повсеместный).

    Валидация email на фронте не даёт 100% гарантию что email верный и существует.
    Можно лишь обязать пользователя соблюсти определённый паттерн.

    Если чистый js, то можно воспользоваться validation api и регулярным выражением.
    https://developer.mozilla.org/ru/docs/Learn/Forms/...
    Ответ написан
    Комментировать
  • Как подключиться к postgres - TypeOrm через Nestjs запущенной в контейнере?

    @q2digger
    никого не трогаю, починяю примус
    Почему блин к 127.0.0.1 ? Вам к базе надо - вместо адреса имя контейнера с базой и пишите.
    host: postgres11
    докер там разберется
    Ответ написан
    3 комментария
  • Перестал работать onclick. В чем проблема?

    @defriz
    люблю js
    уберите атрибут disabled и все заработает.
    Ответ написан
    2 комментария
  • Есть ли способ добавить свои методы не трогая модель в laravel?

    RNSNS
    @RNSNS
    Symfony Backend developer
    На самом деле это очень легко

    #src/Model/ProductProxy.php
    <?php
    
    namespace App\Model;
    
    use ВашПакет\Product;
    
    class ProductProxy extends Product
    {
        public function newMethod(): void
        {
            echo "Hello World!";
        }
    }
    Ответ написан
    Комментировать
  • Что тут не так?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега Laravel
    Вы в запрос вместо id передаёте объект.
    "id" = { "id": 5,
    Ответ написан
    7 комментариев
  • Как быстро добавлять / обновлять миллионы строк в БД Laravel?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Для сферического обновления в вакууме не нужно вообще ничего.
    БД спокойно по умолчанию пишет десятки тысяч строк в секунду.
    То есть просто записывать и всё.

    При возникновении конкретных проблем надо собраться с мыслями и задать конкретный вопрос, детально описывая проблему. А не вот это вот "ну у нас там много всего и растёт нагрузка".

    В качестве чисто гадательной рекомендации поиграться с innodb_flush_log_at_trx_commit / транзакции.
    Ответ написан
    Комментировать
  • Как правильно задать несколько классов элементу?

    Fragster
    @Fragster
    помогло? отметь решением!
    Потому что у тебя ошибка вычисления выражения desktop - news__post - wrapper и m - t_1, о чем он с примерно 99% вероятностью ругается в консоли. Добавь кавычки, чтобы были строки с названием класса. А вообще в твоем случае можно использовать совместно
    class="тут классы, применяемые всегда" :class="тут динамическая часть"
    Ответ написан
    2 комментария
  • Laravel 9 и PHP SDK VK, как связать?

    AmdY
    @AmdY
    PHP и прочие вебштучки
    Пользуйтесь нормальной IDE PHPStrom. Она и сама use подставит и предупредит, если что-то сделали не так. Это же детская ошибка в синтаксисе.
    Ответ написан
    Комментировать
  • Laravel как правильно обновить баланс при покупке?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега PHP
    Нужно просто для всех команд списания с баланса использовать мьютекс, внутри которого:
    1. Получать текущий баланс.
    2. Проверять, что он больше, либо равен сумме списания.
    3. Вносить изменения в БД, если всё ок.
    Третий шаг можно реализовать по-разному - через таблицу транзакций, через единственное поле баланса, как у вас сейчас или ещё как угодно. Эта часть совершенно не важна.
    Важно только то, что функционал списания с баланса в целом становится однопоточным за счёт блокировки.
    Нужно только учитывать, что блокировка должна быть распределённой. Стандартом является использование алгоритма Redlock, реализованном на базе Redis.
    Ещё важно использовать один блокировщик именно для всех типов списаний. Если вы в buyProduct будете использовать один мьютекс, а в каком-нибудь buyService другой, то работать это правильно не будет.
    Ответ написан
    Комментировать
  • Laravel как правильно обновить баланс при покупке?

    iMedved2009
    @iMedved2009
    Не люблю людей
    1. Лочить запись в таблице балансов до момента списания. Залочили, проверили, списали, разлочили. Другие процессы либо будут ждать - либо вылетят по таймауту.

    2. Использовать update с условием. update user_balance where user_id = ? and balance > нужного. У вас запрос не выполнится если кто то уже списал деньги. А вы по affected rows можете судить списалось или нет
    Ответ написан
  • Как сократить запись в v-bind?

    @VolgaVolga
    Откройте для себя "computed".
    Ответ написан
    Комментировать
  • Как освободить зарезервированную оперативную память?

    DamianLewis
    @DamianLewis Автор вопроса
    Написал в техподдержку Lenovo. Ответили следующее:
    На данном устройстве нет возможности изменить количество выделяемой памяти в BIOS. По умолчанию встроенный графический адаптер использует столько оперативной памяти, сколько необходимо для конкретных задач. Некоторые дополнительные параметры можно изменить в настройках Windows. Рекомендуем Вам обратиться в поддержку Microsoft для получения более подробной информации:
    +7 (495) 916-7171, +7 (800) 200-8001
    Онлайн поддержка: https://support.microsoft.com/ru-ru/contactus/


    Через программные решения в работающей системе изменить ничего не получится. Если такая возможность в BIOS'е не заложена, других вариантов решить данную проблему нет.
    Ответ написан
    4 комментария
  • Что лучше? Строить свой интерфейс или же юзать готовые админки типа Filament PHP, orchid, nova?

    Sanes
    @Sanes
    Готовые админки подойдут только для примитивных CRUD операций.
    Я пришел к тому, что потихоньку собираю библиотеку из Blade компонентов Uikit 3 (мне с ним удобно работать).
    Ответ написан
    1 комментарий
  • Как заставить срабатывать Laravel Task Scheduler по заданному расписанию?

    @vism
    2022-08-27 14:35:00 Running [Callback] ............................ 8ms DONE

    вот ведь, работает. это у вас лог не работает видимо
    Ответ написан
    Комментировать
  • Как подключить библиотеку во vue.js 3?

    Fragster
    @Fragster
    помогло? отметь решением!
    ты пытаешься смешать composition api и options api.
    Если пользуешься options api, то убери import { useCookies } from "vue3-cookies";, найди место, где создается экземпляр vue (где-то в index.js или подобном месте ищи createApp()) и добавь туда строки подключения плагина для options api:
    import VueCookies from 'vue3-cookies'
    
    let app = createApp(App);
    app.use(VueCookies);
    app.mount('#app')


    или переходи на composition api и там уже useCookies и вот это все. В принципе, в документации всё описано.
    Ответ написан
    3 комментария
  • Не вызовут ли аттрибуты phpstorm проблем в продакшене?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Не вызовут, если версия РНР "на проде" не меньше 8.0
    Введение в атрибуты
    Ответ написан
    2 комментария
  • Зачем задавать приватный модификатор доступа для свойств класса?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    У вас очень логичный вопрос на счет сеттера: сеттер полностью уничтожает задумку с инкапсуляцией. Правильно это называется "семантическое нарушение инкапсуляции" — то есть как-бы мы инкапсулировали, но по факту назад открыли прямую запись в свойство напрямую. Все доводы "ну мы можем в сеттере валидировать" не корректны

    Правильным способом будет не использовать сеттеры. Вот моя статья на эту тему:
    https://habr.com/ru/post/469323/

    Более подробно: каждый класс нужно проектирвовать так, чтобы данные внутри были максимально связаны. Например каждый метод работать должен в хорошем случае с максимальным числом полей класса, тогда у него высокий cohesion... В тоже время снаружи наужно работать с максимальн омалым числом метода, тогда будет низкая связанность (coupling). Это пара принципов из GRASP.
    Когда вы делаете сеттеры и геттеры, то у вас данные внутри между собой почти никак не взаимодействут: с геттером работают снаружи, с сеттером работаю снаружи — весь класс нараспашку, а в нем в 100% случаев появляются данные, которые вместе не должны находиться и никак не связаны — анрушена и абстракция и инвариант и много чего еще...

    Про инвариант отдельно: например есть платеж, у него есть значение, с которым платеж инициирвоан (initValue), есть значение холда (holdAmount) и есть значение чарджа на списание (chargeAmount)
    Когда вы работаете с платежом, контролируя ивнариант в самом классе, то ваш каждый метод првоеряет др значения и позволяет перейти к др состоянию... методов будет 2-3, все инкапсулировано и безопасно.

    Например:
    class Payment {
         pub func charge(amount int) void {
              if (this.holdAmount < amount && this.initAmount < amount) {
                   throw new PaymentException('Unavailable charge amount')
              }
    
               if (this.status === PaymentStatus:finish) {
                   throw new PaymentException('Payment already fisnished')
              }
    
              this.chargeAmount = amount
              this.holdAmount -= amount
              this.status = PaymentStatus:finish
         }
    }


    Тут в одном методе полные проверки и класс сам контролирует все состояние внутри, также соблюдается закон Деметры. У даннго кода высокий cohesion (из GRASP), тк внутри идет плотная работа с внутр данными (значит они корректно тут закроекны) и низкий coupling ( с теми данными для данного кейса только один метод работы, все внутри)

    Когда вы раскроете сеттерами и геттерами, то ваше состояние становится непредсказуемо и полагается только на то, что снаружи точно подумали об инварианте (нет)
    Ответ написан
    23 комментария