Laravel Сложные запросы и куда их вставлять

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Зачем это называть «виртуальный AR»? Там что, тоже будет метод $myReadOnlyVirtualAr->save(), но «виртуальный»? Просто объект с данными для чтения.
белый рыцарь ордена ddd бросился в атаку на Active Record! :)
я прикалывался - потому что фиксер сказал "нельзя"

только не $myReadOnlyVirtualAr, a $myVirtualAr->save(), который декорирует пишущий объект
 

fixxxer

К.О.
Партнер клуба
я прикалывался - потому что фиксер сказал "нельзя"
"Нельзя" в смысле классического AR.

Сделать отдельные read AR и write AR, конечно, можно. Но я не уверен, что это все еще называется ActiveRecord. Semi-active record? One-way active record? :)

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

Вурдалак

Продвинутый новичок
бросился в атаку на Active Record!
А если ты хочешь сказать, что у классического двустороннего датамаппера ровно та же проблема - да, разумеется, это так.
@grigori во всём видит заговор против ActiveRecord, как негры во всём — расизм. :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
зачем отдельные AR? два сервиса с SQL и логикой, которые выполняют преобразования между уровнем базы и виртуальными сущностями, и поверх них оберткой AR

так пахнет в yii :)
 

AmdY

Пью пиво
Команда форума
А как вывести конкретное поле? Оно выводит весь массив. В интернете примеры с
Код:
$query->select('поле');
Но с select выводит просто []. Пробовал так же в Модель, в методе "salaries" через select, то же самое.
покажи полный код и какую версию фреймворка используешь. select должен работать.
 

fixxxer

К.О.
Партнер клуба
@grigori, я тебя не понимаю.

Вот есть у меня классические "сотрудники" и "отделы", я сделал RO-модель "отделы со статистикой сотрудников", там есть поля employees_count, promoted_employees_count, vacation_employees_count.
Какой смысл будет иметь save() для такого?
 

Alexey Mezenin

Новичок
Эм, а чего там инжектить-то?

Вот есть у меня SomeEloquentModel::findByFoo($foo). Как это заинжектишь?
Инжектить модели. @AmdY как-то здесь пример приводил. Инжектишь в контроллере или другом классе, где используешь модель и:

Код:
$this->someEloquentModel->findByFoo($foo)
И что касается репозиториев, в документации об этом не слова.
Это паттерн. Используй модели. В Laravel это, по своей сути, репозиторий и есть. Есть конечно отдельные пакеты для создания репозитория, но смысл в этой лишней абстракции нулевой, вреда больше. Перескочить с Eloquent на Doctrine ты не сможешь все равно, тебе придется переписывать полностью репозитории. А не трогать контроллеры и другие классы при "переезде" можно и с моделями. Я видел использование пакетов для создания репозиториев только в проектах пяти-десятибаксовых индусов.

А и еще, что скажите на счет форм laravelcollective/html. Для работы с формами ничего нет. Стоит их использовать или нет?
Если ты имеешь ввиду формы, то это супер пакет, советую использовать. Если именно Html::, то бенефитов он не дает.

С формами сэкономишь кучу времени (денег заказчика) и код будет намного более читаемым. Я недавно человеку показал как использовать простые мульти списки - у него код на 15 строк, большинство которых еще прочитать надо. У меня одна короткая читаемая строка с ипользованием laravelcollective/forms.

В прошлом этот пакет был частью фреймворка, но сейчас автор многие функции фреймворка отделяет в отдельные пакеты.
 
  • Like
Реакции: z3r9

Alexey Mezenin

Новичок
А как вывести конкретное поле? Оно выводит весь массив. В интернете примеры с
Код:
$query->select('поле');
Но с select выводит просто []. Пробовал так же в Модель, в методе "salaries" через select, то же самое.
Когда используешь select с отношениями, нужно добавлять ID модели для большинства видов отношений, иначе работать не будет. Для belongsTo() вместо ID модели, нужно добавить внешний ключ, иначе тоже пустой объект вернет.

select() тебе позволит убрать лишнее из ответа, если захочешь вывести само значение, итерируй по модели и используй first(), чтобы вернуть объект коллеции. Ну а потом делаешь ->value для того, чтобы достать необходимое значение.

Например, если ты хочешь "достать" одного работника с его зарплатой и хочешь использовать код @AmdY (немного неверный синтаксис, поправил ниже), то можно сделать что-то подобное:

Код:
$employee = Employee::with(['salaries' => function($q) {
    $q->latest()->take(1);
}])->find($id);

// Работаешь с объектом, который содержит коллекцию:
$value = $employee->salaries->first()->value;
find() достает объект. Если используешь get() или paginate(), то тогда итерируй работников и только потом "доставай" зарплаты.

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

Если тебе нужна value для одного работника, лучше сделать так в модели Salary:

Код:
public function getLastValueByEmployeeId($id) {
    return $this->where('employee_id', $id)->latest()->first()->value;
}
Замени value на название нужного столбца.

Либо в модели Employee:

Код:
public function getLastSalaryValueByEmployee($employeeObject) {
    return $employeeObject->salaries()->latest()->first()->value;
}
Но только если в текущем запросе нужно достать данные для одного работника.
 
Последнее редактирование:
  • Like
Реакции: z3r9

Alexey Mezenin

Новичок
Да не нужно использовать AR для этого, напиши отдельный класс который тупо сделает SELECT-запрос в базу.
Я бы не стал это комментировать, если бы под сообщением не увидел твой лайк, @z3r9. Это индокод, совет на уровне "насри на хорошие практики инструмента и сделай велосипед" или "я никогда не использую ООП, старый проверенный PHP4 way надежнее". Используй ORM и модели, это хорошая практика, которая позволит легко читать и работать с твоим кодом другим Laravel разработчикам (или будущему тебе).
 

fixxxer

К.О.
Партнер клуба
Инжектить модели. @AmdY как-то здесь пример приводил. Инжектишь в контроллере или другом классе, где используешь модель и:

Код:
$this->someEloquentModel->findByFoo($foo)
Лол. Ты понимаешь хоть, что это идентично

PHP:
$user = new User();
$user = $user->findById(1);
вот такому коду?

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

fixxxer

К.О.
Партнер клуба
Используй ORM и модели, это хорошая практика, которая позволит легко читать и работать с твоим кодом другим Laravel разработчикам (или будущему тебе).
Ты понимаешь, что означает слово "модель"? Подсказываю, к базе данных и к таблицам и полям в ней модель не имеет никакого отношения.
 

Alexey Mezenin

Новичок
Лол. Ты понимаешь хоть, что это идентично

PHP:
$user = new User();
$user = $user->findById(1);
вот такому коду?
Не идентично. Я говорю про использование контейнера, твой код тайтит модель к текущему классу.

Ты понимаешь, что означает слово "модель"? Подсказываю, к базе данных и к таблицам и полям в ней модель не имеет никакого отношения.
Давно я на клаб не заходил, сразу же попытки ткнуть в нубство и "уроки" начинаются на уровне "ты знаешь с какой буквы начинается алфавит? с А!!! Лол, дурачок ты".
 

Вурдалак

Продвинутый новичок
Я бы не стал это комментировать, если бы под сообщением не увидел твой лайк, @z3r9. Это индокод, совет на уровне "насри на хорошие практики инструмента и сделай велосипед" или "я никогда не использую ООП, старый проверенный PHP4 way надежнее". Используй ORM и модели, это хорошая практика, которая позволит легко читать и работать с твоим кодом другим Laravel разработчикам (или будущему тебе).
Почитай на тему CQRS, я говорю про разделение чтения и записи. Для записи ORM подходит идеально (find by id, save). Для чтения — намного хуже, особенно когда речь идёт о том, что результат чтения не маппится ни на одну из сущностей и/или когда требуется нетривиальный запрос. Есть ещё несколько моментов помимо чисто технических проблем.

Полагать, что код станет ООП от того, что ты следуешь «лучшим практикам» от автора ORM — это детская наивность.
 

Вурдалак

Продвинутый новичок
Не идентично. Я говорю про использование контейнера
Мы это уже проходили, когда человек узнаёт какой-то приём и пытается пихать его везде, где только может. Так было у меня и у многих других. Инжектить объект, который уже сам по себе является синглтоном — пустая трата времени. Исключение может быть только в том случае, если там в type hinting какой-то интерфейс и явной завязки на этот синглтон нет.

твой код тайтит модель к текущему классу.
Чо? А как выглядит конструктор твоего «текущего класса»? Там в type hinting не будет User?

Вообще забавно, что человек использует AR, целью которого является «херак-херак», чтобы не заморачиваться с инъекцией DataMapper, а потом делает вид, что он использует расово верные подходы.
 

fixxxer

К.О.
Партнер клуба
Давно я на клаб не заходил, сразу же попытки ткнуть в нубство и "уроки" начинаются на уровне "ты знаешь с какой буквы начинается алфавит? с А!!! Лол, дурачок ты".
@Alexey Mezenin, таких учителей, как ты, только так и можно. С твоим текущим уровнем познаний надо воздерживаться от раздавания категоричных советов и всегда уточнять, что это только твое мнение.

К чему приходит обратный подход с сюсюканьем, можно прекрасно видеть на StackOverflow.
 

Вурдалак

Продвинутый новичок
@Alexey Mezenin, таких учителей, как ты, только так и можно. С твоим текущим уровнем познаний надо воздерживаться от раздавания категоричных советов и всегда уточнять, что это только твое мнение.
Справедливости ради, он не может осознавать свой уровень познаний, это же известная тема. :)
 

AmdY

Пью пиво
Команда форума
Вместо трёх строчек кода набросали кучу теории, о которой даже сами зачастую договориться не можете. Да, Д'Артаньяны.

@fixxxer ну ты же адекватный человек, должен же понимать, что понаписывает человек,накурившийся DDD на форумах, который не смог даже документацию laravel освоить.
 

Вурдалак

Продвинутый новичок
Вместо трёх строчек кода набросали кучу теории, о которой даже сами зачастую договориться не можете. Да, Д'Артаньяны.

@fixxxer ну ты же адекватный человек, должен же понимать, что понаписывает человек,накурившийся DDD на форумах, который не смог даже документацию laravel освоить.
Во всём треде о DDD упомянули @grigori и ты. Ты не перепутал ветку?
 

fixxxer

К.О.
Партнер клуба
Вместо трёх строчек кода набросали кучу теории, о которой даже сами зачастую договориться не можете. Да, Д'Артаньяны.

@fixxxer ну ты же адекватный человек, должен же понимать, что понаписывает человек,накурившийся DDD на форумах, который не смог даже документацию laravel освоить.
И где я что-то говорил про ДДД?
 
Сверху