• Вопрос о тестах. Что вы об этом думаете?

    Проблема такого теста в том, что он тестирует сразу две вещи:
    1. Что работает api
    2. Что работает Model::factory()->make()->toArray(), которая генерирует аргументы для вызова api

    От этого возникают следующие проблемы:
    1. Без изменения кода api у тебя тест может неожиданно начать падать и наоборот.
    Например ты поменял названия параметров. Тест зелёный, тк фабрика генерит параметры, а клиенты все теперь 400-е ошибки получают.
    Контракт получается незафиксированный.
    2. Ты не можешь при таком подходе нормально проверить негативный сценарий и граничные значения.
    Чтобы их проверить - тебе всё также придётся отказаться от Model::factory()->make()->toArray() и составлять параметры руками.

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

    iMedved2009
    @iMedved2009
    Не люблю людей
    Бизнес-логике - не место в контроллере.

    AppServiceProvider
    public function boot(){
    Validator::extend('count_books', function($attribute, $value, $parameters) {
            $count = IssueBook::where('client_id', $value)->where('is_returned', false)->count()
            return $count < 2;
    });
    }
    
    StoreRequest
    public function rules()
      {
        return [
          'category_id' => 'exists:App\Category,id',
          'client_id' => 'exists:App\Client,id|count_books',
          'book_id' => 'exists:App\Book,id',
          'days_issued' => 'nullable|string',
          'is_returned' => 'nullable|boolean',
          'return_date' => 'nullable|date',
        ];
      }
    Ответ написан
  • Как поступить с заказчиком?

    SeaInside
    @SeaInside
    15 лет пилю все эти штуки
    Вы ведь сами понимаете, что это ваш косяк, а не заказчика? А чего ему за него платить?

    Мне прям вспомнилась ситуация, когда я пришёл к стоматологу вылечить кариес (пусть будет 2 000 рублей), мне рассверлили весь зуб и заявляют "батюшки, да тут же пульпит!" (12 000 рублей).
    Помогите Маше найти фразу для стоматолога, которая позволила бы сохранить хорошие отношения.

    И вот вы сейчас, по прошествии 2 месяцев, оставите заказчика один на один с незавершённым проектом, в котором никто не разберётся (то есть по сути ни с чем) - то вы поступаете как чудак. Я же вижу по тексту, что понимаете.
    А сюда вы за индульгенцией пришли? :)

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

    Если совсем невмоготу - возвращаете оплату целиком и сильно извиняетесь (можно даже сверху накинуть).
    В таком случае о хороших отношениях говорить не приходится, но послевкусие хотя бы как от порядочного человека.

    Два совета на будущее:
    1) Перезакладывать стоимость и время разработки;
    2) Если понимаешь, что всё идёт не по плану/пропал интерес / слишком сложно / некомфортно / whatever - сказать об этом сразу и отказаться от проекта, так всегда получается честнее

    Опыт всегда стоит дорого, а 53 000 рублей - ну не самая большая цена его получения :)
    Ответ написан
    8 комментариев
  • Как задать пути к файлам на сервере?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега Laravel
    Подобные проблемы решаются в принципе корректной настойкой сервера.
    Ответ написан
    Комментировать
  • Три цены, одна дефолтная, 2 зависят от чекбоксов, как все плюсовать?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    2 комментария
  • Я сделал Code Review, может быть я где-то ошибся или у вас есть что добавить?

    @Sing303
    Опишу, как бы комментировал я
    public sealed class DataProvider : IDisposable
    {
        // nit: Предложил бы названия firstValue, secondValue либо более осмысленные, если возможно
        public extern int LongRunningCalculation(int value, int value2);
        public extern void Dispose();
    }
    
    // nit: сразу бы хотелось видеть уровень доступа и sealed (если класс не планируется наследовать)
    // Class2 - дать нормальное имя
    // { - перенести на 2ю строку по рекомендациям code style от microsoft (если не принято иных)
    class Class2 {
        // Синхронизация не нужна, если убрать метод Init, а Create вызвать в статическом конструкторе
        private readonly object _sync = new object();
        
        // _ht - дать осмысленное название
        // Судя по использованию, value может быть int`ом. Не зачем иметь лишний boxing и проверки на тип
        // _ht статический, значит к нему могут быть обращения из разных потоков, лучше сделать его ConcurrentDictionary
        // Прям сходу не могу сказать, но, возможно, использовал бы какой то другой тип Dictionary <key, key, val> (самописный или существующий), кажется, так было бы быстрее чем массив в ключе
        private static Dictionary<int[], object> _ht; 
    
        // nit: хотелось бы имена со смыслом
        public int GetValue(int index, int index2)
        {
            // Лишний метод, удалить. Create вызовем в static конструкторе
            Init();
            // Если ключ у нас объект, то необходимо реализовать IEqualityComparer для этого Dictionary (иначе не понятно как по нему искать)
            var key = new[] {index, index2};
            // Проверка на тип не нужна, Dictionary сделаем типа int
            if (_ht.ContainsKey(key) & _ht[key].GetType() == typeof(int))
                // приведение типов больше не нужно
                return ((int)_ht[key]);
            // nit: else не обязателен
            else
                // int не может быть null, будет ошибка, вернуть либо default, либо возвращаемое значение должно быть int?
                return null;
        }
    
        // Метод удалить, вызовем Create в статическом конструкторе без lock
        public void Init() 
        {
            if (_ht == null)
                lock (_sync)
                    Create();
        }
        
        // Нет смысла делать метод public, сделать private
        public static void Create() 
        {
            // nit: и так видно какой тип создаём, можно использовать var
            // Обернуть в using
            DataProvider provider = new DataProvider();
            
            // Тут следует инициализировать значение _ht, т.к. ранее оно нигде не создаётся
            // Не забыть передать реализацию IEqualityComparer в конструктор
            
            // nit: хотелось бы видеть использование фигурных скобок (если не принят иной code style)
            // nit: вместо int можно var
            // i и j, похоже, несут какой то смысл, можно попробовать придумать нормальное название (иначе не понятно почему 100 и 12, их можно в константы класса)
            // nit: возможно можно использовать Parallel.ForEach
            for (int i = 0; i < 100; i++)
                for (int j = 1; j <= 12; j++)
                    _ht[new [] { i, j }] = provider.LongRunningCalculation(i, j);
        }
    }

    А переписал бы так (если не убирать массив в dictionary)
    public interface IDataProvider : IDisposable
    {
        int LongRunningCalculation(int firstValue, int secondValue);
    }
    
    public sealed class DataProvider : IDataProvider
    {
        public extern int LongRunningCalculation(int firstValue, int secondValue);
        public extern void Dispose();
    }
    
    public sealed class DataProviderService
    {
        public DataProviderService(IDataProvider dataProvider)
        {
            _dataProvider = dataProvider;
        }
    
        private static readonly ConcurrentDictionary<int[], int?> _calculatedCache = new ConcurrentDictionary<int[], int?>(new CalculatedEqualityComparer());
        private readonly IDataProvider _dataProvider;
    
        public int? GetValue(int firstValue, int secondValue)
        {
            var isNotSupportedValues = firstValue > 100 || firstValue < 0 || secondValue < 1 || secondValue > 12;
            if (isNotSupportedValues)
            {
                return null;
            }
    
            var key = new[] { firstValue, secondValue };
            if (!_calculatedCache.TryGetValue(key, out var result))
            {
                result = _dataProvider.LongRunningCalculation(firstValue, secondValue);
                _calculatedCache.TryAdd(key, result);
            }
            
            return result;
        }
    }
    Ответ написан
    5 комментариев
  • Как понять микросервисы?

    @deliro
    Как понять микросервисы?

    Прочитать соответствующую книгу (а лучше ещё парочку про DDD или хотя бы посмотреть этот доклад)

    Затем ответить на несколько вопросов:
    1. Почему вы решили, что микросервисы что-то вам дадут?
    2. Есть ли у вас настоящие причины для микросервисной архитектуры? (А именно: зоопарк технологий с невозможностью написать 99% на одном языке; более тысячи разработчиков; сложность выкатки монолита в виде часов прогонов CI/CD — тестов, билда, деплоя, стопоров выкатки в виде кучи проблем из-за разработчиков; вы такие же большие как гугл, убер, амазон и т.п.). Или вам просто нравится модное слово "микросервисы"?

    Не получится создать хорошую микросервисную архитектуру без умения создать хороший модульный монолит. В этом случае вы получите не только все проблемы плохого монолита: высокая связанность, каскадные падения, долгий CI/CD; но и все проблемы микросервисов: их надо оркестрировать (у вас же есть команда, которая будет поддерживать инфраструктуру?); каждому микросервису нужно своё CI/CD (и хорошее); сеть может (и будет) лагать и обрываться; длительность запросов увеличится на порядок(ки) (особенно если выбрать какой-нибудь JSON-RPC over HTTP); нужно предусмотреть failover strategy (например, идемпотентные ретраи. Вы же уже знаете про correlation id, саги и что делать, если прилетел network error на запрос в другой сервис "списать 10 баксов"?) и circuit breakers; трейсы и логи, которые не пришлось бы искать по сотням .log файлов от каждого сервиса; бизнес-логика расползётся по разным микросервисам и нарушит SRP (пофиг, что нарушит, важнее то, что это починить будет сильно сложнее). Список можно продолжать долго.
    Ответ написан
    11 комментариев
  • Есть ли шанс стать востребованным js, html/css программистом на фрилансе учитывая огромную конкуренцию?

    approximate_solution
    @approximate_solution
    JS Developer. Angular\React\Vue\Ember
    На правильном ли я пути, что учу javascript в плане карьеры?

    Если в компанию - то да, если фриланс - нет.

    Смогу ли я уверенно выполнять заказы на фрилансе выучив javascript?

    Нет, сам javascript никто не использует(имеется ввиду не верстка типовых лендосов, которые стоят 3 копейки, а более сложных проектов в виде SPA), используют over1000+ библиотек и решений которые крутят js под капотом. Что бы их валидно применять к конкретной бизнес задаче - нужен уровень не ниже мидла как разработчика, и уровень не ниже менеджера средней руки - что бы всё это продать за хорошую цену.

    И стать востребованным?

    Учиться 2-3 года, желательно после 1го года учебы максимально быстро попасть на: а) стажировку, б) работу.
    Ответ написан
  • Почему не работает whereHas?

    New_Horizons
    @New_Horizons Автор вопроса
    Бред:
    $products = Product::with('gifts')
    	->where('is_gift', '=', false)
    	->whereHas('gifts', function (Builder $query) {
    		$table = $query->getModel()->getTable();
    		$query->where("{$table}.id", '=', 4);
    	})
    	->get();
    Ответ написан
    3 комментария
  • В чем ключевое ПРАКТИЧЕСКОЕ отличие статических переменных и методов от обычных? Просто более компактный код?

    Adamos
    @Adamos
    class Demo {
      static private $db = null;
      static private $cache = [];
    
      static protected function getDb() {
        if(self::$db === null) {
          self::$db = ... // init $db
        }
        return self::$db;
      }
    
      static protected function cachedAction($arg) {
        if(!array_key_exist($arg, self::$cache)) {
          self::$cache[$arg] = ... // do action
        }
        return self::$cache[$arg];
      }
    }
    
    class DemoChild : public Demo  {
    }
    
    $a = new Demo();
    $b = new DemoChild();
    $a->getDb()->query();
    $b->getDb()->query(); // uses the same connection
    $c = $a->cachedAction('one');
    $d = $b->cachedAction('one'); // no action, cache used
    Ответ написан
    1 комментарий
  • Как задать маршрут в laravel, если кол-во опций неизвестно?

    solotony
    @solotony
    покоряю пик Балмера
    я явно формировал маршрут /a/b/c/ для "пост" и записывал его в бд.
    потом все "непонятные" URL просто проверял по б/д
    Ответ написан
    2 комментария
  • Как программисту отдыхать и организовать распорядок дня?

    На удаленку. 4 часа в день без выходных выдавать нагрузки по задачам. Будет 120 часов в месяц, офисная норма. Устать не возможно.
    Ответ написан
    Комментировать
  • Как программисту отдыхать и организовать распорядок дня?

    @podde
    самый младший сисадмин
    Не вините себя. У вас объективно очень много времени уходит на дорогу.
    Совершенно серьёзно думаю, что в такой ситуации надо попробовать поговорить с руководителем на предмет хотя бы частичной (пару раз в неделю) удалённой работы. А лучше попробовать вообще выпросить удалённый режим.
    Если нет – пробовать искать другую работу (поближе к дому или удалённую).
    Ну, действительно, по пять часов в день на дорогу – это не дело.
    Ответ написан
    Комментировать
  • В сфере IT для новичков нет перспектив?

    @nApoBo3
    Это сложный вопрос. На первый взгляд на низовых позициях в ИТ дикая конкуренция. С другой стороны, она дикая но совершенно беззубая, поскольку уровень кандидатов соответствует дворнику.
    Месяц назад искал себе помощника помощника, кандидатов море, уровень ниже плинтуса, не знают ничего совсем, две кнопки выучили и вот уже ИТ специалист.
    Работа, это все таки не школа и не институт, тут вы в замен тоже что-то должны дать, т.е. должны делать какую-то работу полностью самостоятельно и с должным качеством. Если вы что-то умеете делать самостоятельно и полностью понимаете процесс, то вот такую работу и ищите. То что кто-то может next, next, finish, поставить windows ИТ специалистом данного человека не делает.

    Вот и получается, конкуренция дикая, но среди перспективных ее практически нет.
    А перспективные это те, кто понимают, чтобы получить нужно сначала вложить, и много, и регулярно вкладывают в себя.
    Ответ написан
    3 комментария
  • В сфере IT для новичков нет перспектив?

    prrrrrrr
    @prrrrrrr
    Верстаю сразу на PHP.
    ...а требования (по знаниям и опыту) как к высококвалифицированному специалисту

    всё правильно. помощник для того чтобы помогать программисту делать то, что делает он, и использовать те технологии которые использует он.
    у меня есть тоже знакомый который постоянно проситься ко мне "помощником" за копейки, но нафиг он мне нужен если он в программировании 0. в чём он сможет мне помогать? отвлекать?

    Ну как начать работу, если никуда не берут

    для начала нужно как минимум что то знать
    Ответ написан
    7 комментариев
  • Очень хорошо знаю PHP - куда двигаться дальше?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Хайлоад

    Сразу поймёшь, что ничего не знаешь вообще
    Ответ написан
    2 комментария
  • Как сделать две формы регистрации для разных типов клиентов в laravel 7?

    qant
    @qant
    programer
    Да уж... вам явно рановато ларавел изучать ) если такие базовые вещи заставляют писать такой вопрос...
    Задавать конечно вопросы не стыдно и даже полезно, это нормально на старте, но причем тут Ларавел 7? Вам нужно изучить базу php. Желательно с учетом новых версий php-7+

    Далее нужно просто изучить несколько примеров "Как создать форму php" "как отправить форму php" "как отправить форму php ajax"

    Изучив разные примеры, вы поймете принцип, как работает отправка формы из html и этот вопрос отпадет сам собой
    И вы поймете что количество форм на странице может быть любым, более того, одну и ту же форму можно использовать для регистрации и пользователя и администратора добавив всего один параметр (например роль, который будет использоватся для проверки в коде)
    Ответ написан
    Комментировать
  • Laravel структура контроллеров?

    glaphire
    @glaphire
    PHP developer
    Фронтенд, личный кабинет и админка - разные по логике модули, для независимого развития кода больше всего подходит пункт 1. Общую логику всегда можно вынести в сервисы/хелперы и через DI передавать контроллерам
    Ответ написан
    8 комментариев
  • Какой кешер для php лучше? Как выбрать?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Никакой.

    Судя по тому, что ты путаешь opcode cache с data cache, кэш тебе вообще никакой не нужен, а вопрос задан от балды.
    Учись мудрости у природы: когда коту делать нечего, он не кэш ищет, а гигиену наводит. И это очень правильное занятие в твоей ситуации. Куда меньше вреда принесёт
    Ответ написан