• Как правильно работать с Adjacency List в Eloquent/Laravel, если ключ типа uuid?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Ну вот что я и писал вчера. Как взлетать с Ларавель никто не знает, так обозвали меня и погнали палкой за вопрос

    Потому что если взглянуть в исходник, то
    public function saveMany($models)
        {
            foreach ($models as $model) {
                $this->save($model);
            }
    
            return $models;
        }


    И где ты тут айдишники видишь?
    Он тупо залил, в базе наверное 0 по умолчанию (NOT NULL DEFAULT 0). Или в модели сразу стоит
    $attributes[] = ['parent_id' => 0];

    Добро пожаловать в мир ларавеля, где все знают что он прекрасен, но тебе никто не поможет, потому что он же прекрасен

    Тут конечно нет никакой идеи, но если предположить что я её понял, то там так
    foreach ($childrens as $child) {
      $child->parent()->associate($child)->save();
    }


    Хотя если порыться глубже, то там вроде как присутствует ->setForeignAttributesForCreate(), который должен это делать, но ему то ли геттер не отдает значение, то ли сеттер лочит установку, то ли там еще тыща причин, кроче dd($relation = $this->childSections()), исходник в руки и каждый шаг на экран

    Почему нельзя наоборот? А хрен его знает
    Ответ написан
  • В каком формате хранить значения nanoseconds?

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

    превратив в строку и разбив по точке, можно с ним работать с помощью bcmath и сразу видеть что вот секунды, вот нано.
    Ответ написан
    Комментировать
  • Как в Eloquent запросить все значения некоторого атрибута, который имеет связь many-to-many?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Попробуй так:

    Products.php
    public function attributes()
    {
    return $this->hasManyThrough(Attributes::class, ProductsAttributes::class...); // тут надо загуглить правильный порядок ключей, не помню
    }

    $product = Products::first(); // берем продукт
    $query = $product->attributes(); // создаем запрос SELECT FROM attributes WHERE exists({subquery});
    $query->select('value')->where('id', 1)->get(); // все значения value, привязанные к первому продукту для аттрибута 1 (но здесь дичь какая-то обычно один атрибут на один продукт, а у тебя получается типа продукт может содержать аттрибут 1 несколько раз?)

    Если нужно вообще все values для всех продуктов то сразу
    Attributes::where('id', 1)->select('value')->get();
    Ответ написан
    Комментировать
  • Laravel 5.8. Почему не работает мутатор?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Либо ты не передал $_POST['slug'] / $_GET['slug']

    Потом ты передаешь в slug $value, а потом его не используешь - берешь $this->manufacture. Он скорее всего пустой, потому что ты новую модель создаешь
    1) то есть он попробует SELECT * FROM manufacturers WHERE ... (пустой запрос в базу, если база на 300 пинге в облаке, +350мс на создание страницы)
    2) даже если это будет делаться на существующей модели - оно конечно сделает SELECT * и вытянет тебе все поля. Для этого обязательно используют with();

    Стоп чо? ты находишься в manufacture.php, там у тебя setSlug() и внутри $this->manufacture.... У тебя связь parent/child внутри этой таблицы? Откуда ты решил взять $this->manufacture?
    Ответ написан
    Комментировать
  • Как правильно пользоваться ресурсами в laravel?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Так это у тебя ясно написано запустить маппер для дочерних обьектов внутри которых запустить маппер для родительских. Ну вот тебе и рекурсия, нет?

    Ресурс это считай array_map();
    Метод collection() это просто array_map() для array_map()

    Пытаясь сделать ресурс для юзера, делаешь внутри ресурс для специальности, которая потом обратно делает ресурс для юзера.

    Это сломалось потому что у тебя есть связь в обе стороны и получается замкнутый круг (он еще граф называется). Тебе надо из графа дверь сделать, признак по которому твой маппер понимает что там он уже был

    Кроме того маааленький сюрприз - у тебя идет обращение к связанной модели, а поскольку скорее всего ты до этого не сделал with('specialitiesResource') то оно у тебя еще и запрос к базе в рекурсии делает

    И второй сюрприз, еще поменьше, когда ты маппишь коллекцию юзеров, то он для каждого юзера делает запрос в базу для каждой специальности. Дважды n+1 query в рекурсии
    Ответ написан
  • Кто сталкивался с такой странностью laravel? Как объяснить?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Может я не ас, но
    $this->data['categories']->map->only(['id'])

    1. map это метод... разве их можно обратиться к методу как к свойству в ларе? А если у тебя есть свойство `map` то будь осторожен, в ларе есть такой метод, а внутри там под капотом чуть ли не сравнение property_exists() method_exists() и всё на магии, можешь ухреначить свою модель и будет вопрос "как она вообще работает" а не "почему она неправильно работает"

    2. only это для выборки если ты из массива сделал коллекцию
    collect([ 'name' => 'vasia', 'age' => 30 ])->only('name'); // [ 'name' => 'vasia' ];
    Roles::get()->only(['id' => 1]); // object Roles#1 (id => 1, title = ...)

    3. чтобы взять список айдишников надо
    $categories->pluck('id')->all(); // [1,2,3]

    По поводу растягивания на 5-6 секунд - видишь ли у лары внутри очень много магии. Вероятно она или ищет, или пытается сделать toString() который там под капотом какой-нибудь serialize() вызывает. В общем говоря оно то работает, но запрос там получится из лютой дичи, WHERE id IN ({json}, {json}) и еще какой-то херни понаделает

    Дебажить запросы var_dump($query->toSql(), $query->getBindings()); и смотришь.
    Ответ написан
    1 комментарий
  • Как вывести все отношения таблиц в laravel?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    $projects = Project::with('roles'); // сформировать запрос на проекты и заготовить запрос на роли. Запрос на проекты при запуске выполнит еще и второй.
    foreach ($projects as $project) {
    $roles = $project->roles; // модели ролей по данному проекту
    }

    $project = new Project(); // создать новую модель ИЛИ
    $project = Project()::first(); // выбрать первую модель из базы

    $query = $project->roles(); // сформировать запрос, который потом нужно выполнить. В качестве WHERE id= будет использован $project->id; Если его там не было - бесполезный запрос, который ссуко все равно будет отправлен на сервер базы данных
    $query->get(); // список ролей или пустая коллекция

    $project->roles; // сразу список ролей (он еще и запросит если не был запрошен через with())

    Будь внимателен, под капотом сделается запрос на роли, если ты его не сделал через with('roles'). Если ты это напишешь в каком-нибудь геттере типа так
    public function getMyAttribute() { return $this->roles; }

    то ты познакомишься с "n+1 проблемой", это когда для сотни проектов будет выполнено 100 запросов на роли.
    Ответ написан
    Комментировать
  • Как подключить сервер на push-уведомления пользователя?

    gzhegow
    @gzhegow Автор вопроса
    aka "ОбнимиБизнесмена"
    Разобрался, через mpg25 апишку можно проставить сначала following, затем favorite, и когда есть фаворит - можно через тот же код поднять сервер, который от имени юзера подключиться на Пуш-канал. Пуш-канал работает строго для favorited.

    Нужно поднять скрипт while (true) и вызвать метод c ловлей пуш-уведомлений.
    Но думаю, Инста быстро прикроет тему если их будут тысячи. Поэтому надо писать систему куда можно быстро добавить еще пару логинов, в каждый из которых фаворитить свои аккаунты, за которыми следить

    Не простая система, но в целом реализуемая
    Ответ написан
    Комментировать
  • Веб приложение jquery + php + mysql. Как открыть вкладку внешнего сайт и перенести туда js код?

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

    если ты хочешь лайк поставить или репост - в вк есть модули для вставки на свой сайт. а пустить человека в вк, чтобы отправить его обратно не выйдет.

    но если бы ты предположим владел вк и пытался такое сделать то есть хрень такая jsonp, когда ты пересылаешь имя метода, заранее написанного во второй системе и вызываешь его на стороне клиента.

    но из разработчиков вконтакте для тебя такого никто писать не будет.
    Ответ написан
    Комментировать
  • Как правильно обернуть инициализацию jqueryUI слайдера?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Для начала
    jQuery = $.noConflict(); // удалить глобалку jQ, делать сразу после запроса к файлу jquery.min.js
    Некоторые древние деды нашей профессии любили свою главную библиотеку в доллар совать. Не важно - jquery это или нет. Бывает что две библиотеки одна заменяет другую и не работают потом обе.

    потом вот так:
    (function ($, App) {
      // ваш код
      $(function () {
        // ваш код после DOM-ready
      });
    })(jQuery, App = window.App || {});


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

    * важно помнить что высота некоторых элементов с overflow: hidden появится только через несколько секунд после загрузки страницы, когда все элементы будут отрисованы. То есть не спасает даже ondomready - нужно делать задержку на пару секунд или плакать в форум разрабам jQuery, давно пора это сделать уже

    * иногда полезно работать с onload для <script src=""> чтобы поймать событие когда скрипт будет подключен к сайту, но еще до того как будет закончен ondomready

    * и я вижу у вас в коде $(document).change() - не знаю что у вас там конкретно происходит, смотреть надо, но я бы на $(document) вешал только две вещи (вообще только две) - mousemove, mouseup - если они требуются. Mousemove - всевозможные ползунки, mouseup - отпускание зажатой ранее клавиши мыши для торопливого пользователя, который любит мышкой двигать с зажатой кнопкой.

    Вешать onchange на документ... интересно, сколько сотен раз выполняется ваше действие?
    Ответ написан
  • Какую книгу по веб-разработке лучше для начинающего, актуальные на сентябрь 2017?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Устал повторять что лучше обучения чем с другим человеком быть не может. Отец-индеец не дает сыну книга как метать копье, он берет его на охоту и говорит "делай как я".
    Ответ написан
    2 комментария
  • Можно ли где-то найти дамп большой БД?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    <?php
        $host = '127.0.0.1';
        $db   = 'test';
        $user = 'root';
        $pass = '';
        $charset = 'utf8';
        $dsn = "mysql:host=$host;dbname=$db;charset=$charset";
        $opt = [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false,
        ];
        $pdo = new PDO($dsn, $user, $pass, $opt);
        for ($i = 0; $i < 1000000; $i++) {
          $pdo->query(sprintf('INSERT INTO table (id, value) VALUES (%d, "%s")', $i+1, uniqid());
        }
    Ответ написан
    Комментировать
  • Как сверстать justify-content: space-between так, чтобы при наличии одного/двух элементов они вставали в flex-start?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    .list
      display block
      font-size 0
    
    .list__item
      display inline-block
      font-size 1rem
      width 33.33333334%


    И ничего не поедет.
    Ответ написан
    Комментировать
  • Как сделать 301 редирект для всего сайта с http и www на https без www?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Универсально и под любой проект. Отредактируйте, т.к. тут идет редирект на https://www., если сервак не тестовый и не локальный.

    # -- FORCE HTTPS
    <IfModule mod_rewrite.c>
      RewriteEngine On
    
      RewriteCond %{HTTP_HOST} ^test. [NC]
      RewriteCond %{HTTP_HOST} \.loc$ [NC]
      RewriteCond %{HTTPS} =on [OR]
      RewriteCond %{HTTP:X-Forwarded-Proto} https
      RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,QSA]
    
      RewriteCond %{HTTP_HOST} ^test. [NC]
      RewriteCond %{HTTP_HOST} \.loc$ [NC]
      RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
      RewriteRule .* http://%1/%{REQUEST_URI} [R=301,L,QSA]
    
      RewriteCond %{HTTP_HOST} !^test. [NC]
      RewriteCond %{HTTP_HOST} !\.loc$ [NC]
      RewriteCond %{HTTP_HOST} !^www\. [NC]
      RewriteCond %{HTTPS} !=on
      RewriteCond %{HTTP:X-Forwarded-Proto} !https
      RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,QSA]
    
      RewriteCond %{HTTP_HOST} !^test. [NC]
      RewriteCond %{HTTP_HOST} !\.loc$ [NC]
      RewriteCond %{HTTPS} !=on
      RewriteCond %{HTTP:X-Forwarded-Proto} !https
      RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,QSA]
    </IfModule>
    Ответ написан
  • Как снаружи прервать выполнение асинхронной функции?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Сделай на Promise();
    Тогда тебе наружу надо просто выкинуть Промис и в другом потоке вызывать Promise.resolve(); и не нужно будет ждать пока первый поток вызовет.

    Придется немного пересмотреть логику но выйдет примерно так:
    1. Ты ждешь от промиза некоего результата или ошибки
    2. В другом потоке произошло нечто, что требует закончить действие. Возвращаешь из другого потока реджект с массивом, в первом параметре код ошибки, во втором сообщение.

    Работаешь как будто получил эти данные из основного промиза, дважды он не резолвнется и не реджекнется.
    Ответ написан
    Комментировать
  • Как правильно написать синхронную ожидалку на JS?

    gzhegow
    @gzhegow Автор вопроса
    aka "ОбнимиБизнесмена"
    Пока заработало вот так:
    вместо того чтобы запускать таймер для каждого запроса в пачке написал вот такую примерно конструкцию:
    co(function* () {
      var limit_burst = default_limit_burst;
      var limit_minute = default_limit_minute;
      var limit_day = default_limit_day;
    
      // getting records from somewhere
      var records = get_the_records();
    
      records = yield co(function* () {
        var records_done = [];
        while (records.length) {
          let limit = Math.min(limit_burst, limit_minute, limit_day);
          let batch = records.splice(0, limit);
          
          // update limits
          limit_burst -= batch.length;
          limit_minute -= batch.length;
          limit_day -= batch.length;
    
          for (let i in batch) {
            // ... request
          }
    
          // refresh limits from response headers if available
          yield Promise.all(ps).then(results => {
            var current_limit_burst = default_limit_burst;
            var current_limit_minute = default_limit_minute;
            var current_limit_day = default_limit_day;
    
            // save results
            records_done = results.map(r => {
              if (r[0] !== null) return console.error(r[1]) || null;
              current_limit_burst = Math.min(current_limit_burst, r[2][0]);
              current_limit_minute = Math.min(current_limit_minute, r[2][1]);
              current_limit_day = Math.min(current_limit_day, r[2][2]);
              return r[1];
            }).filter(r => r!==null);
    
            limit_burst = current_limit_burst;
            limit_minute = current_limit_minute;
            limit_day = current_limit_day;
          });
    
          if (limit_burst <= 0) yield new Promise(r => setTimeout(r, 5000));
          if (limit_minute <= 0) yield new Promise(r => setTimeout(r, 60000));
          if (limit_day <= 0) yield new Promise(r => setTimeout(r, 86400000));
        }
    
        return records_done;
      });
    });
    Ответ написан
    Комментировать
  • Реально ли зучение фреймворков js, без изучения js?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Голову сломаешь себе, не пробуй. у яваскрипта очень много особенностей, которые очевидны и логичны, но которые не сделаны во многих других языках программирования, поэтому путаницы будет очень много.

    Фреймворки можно было бы учить без самого языка если бы у нас воспитание было изначально другое и очень логичное если-то. А так придется переучиваться и ломать голову и проще это сделать на самом js, чем на фрейме
    Ответ написан
    Комментировать
  • Как сделать многоязычное отображение служебных сообщений на PHP?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    А еще есть такой стандарт любопытный - .po/.mo файлы, и их редактор - Poedit. С ними очень здорово танцевать, когда языков больше 4, а файлов больше 100.
    Ответ написан
    3 комментария
  • Что конкретно делает Google PageSpeed Module?

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

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

    там бывают приколы типа картинка не загружается вообще. почему - потому что у тебя в htaccess есть правило редиректа с английского языка на рут - и оно везде заменяет /en на /, а в слово pagespeed-encoundted - есть en.

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

    Так что штука противоречивая. На решение из коробки поставил-забыл даже близко не похоже. Хотя претендует.
    Ответ написан
    Комментировать