Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 Re: Laravel 5.x » Соединение коллекций » 30.07.2017 15:13:47

А каким образом добавить пагинацию?
$actions = $collection->merge($clinic)->merge($analyze)->paginate(10); - так выдает ошибку.

#2 Re: Laravel 5.x » Как сформировать запрос для сортировки по связанной таблице? » 17.05.2017 20:43:25

constb пишет:

->join не нужно делать. вообще элоквент не любит джойны и группировки – они нарушают принцип «одна запись из базы – одна сущность в моделях», посколько могут вернуть несколько записей на одну модель, в случаях когда а) запрашивается связь один-ко-многим со стороны «один» или б) запрашивается связь многие-ко-многим. данный пример соответствует случаю (а)

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

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

ps. обрати внимание ещё на имена полей и моделей. у элоквента конечно широкие возможности настраивать это добро (которые ты и используешь в связях), но есть определённые соглашения по умолчанию, которым лучше следовать, и тогда код будет чище и читабельнее (а если кому-то потом придётся дорабатывать твой код – ещё и проще разобраться будет). во-первых, если назвать поле связи doctor_id то на связях его имя указывать будет не нужно – элоквент сам сгенерирует его из имени модели (Doctor), во-вторых, имена моделей должны следовать PSR2 (никаких подчёркиваний) и быть в единственном числе – то есть в твоём случае модель должна называться DoctorReview и элоквент по умолчанию будет искать записи в doctor_reviews – тебе не нужно будет нигде это имя явно прописывать.

Рассматривал этот варианте, но думал запросом будет проще(((
За имена моделей и полей спасибо, буду теперь в курсе.

#3 Laravel 5.x » Как сформировать запрос для сортировки по связанной таблице? » 16.05.2017 17:57:11

lahno
Ответов: 2

Версия Laravel: 5.4
Версия PHP: 5.6

Задача, что должно происходить _в целом_, техническое задание:
    Нужно реализовать сортировку по связанной таблице.
    Есть таблица doctors(id, name, desc) и reviews_doctors(id, name, text, recommends) Связь один ко многим.
    Нужно отсортировать всех врачей по популярности(количеству положительных отзывов(recommends = 1))

app\Http\Controllers\DoctorsController.php

//Пока дошел до такого:
$doctors = Doctor::with('reviews')
                ->join('reviews_doctors', 'doctors.id', '=', 'reviews_doctors.id_doctor')
                ->orderBy('reviews_doctors.recommends', 'asc')
                ->get();

//Но это не совсем то что мне поможет(((

app\Models\ReviewsDoctor.php

public function doctor()
    {
        return $this->belongsTo('App\Doctor', 'id_doctor', 'id');
    }

app\Models\Doctor.php

public function reviews() {
        return $this->hasMany('App\Reviews_doctor', 'id_doctor', 'id');
    }

#5 Laravel 5.x » Почему не работает Ajax в Laravel 5.4? » 07.05.2017 14:20:48

lahno
Ответов: 2

Версия Laravel: 5.4
Версия PHP: 5.6

Задача, что должно происходить _в целом_, техническое задание:
    Нужно сделать автокомплит на поле поиска. Использую Jquery UI (Autocomplete)

Что произошло, текст ошибки, если есть:
    Даже не отправляется запрос

Код:
Routes:

//routes/web.php
Route::get('/search/autocomplete', ['uses'=>'SearchController@autocomplete', 'as'=>'autocomplete']);

app\Http\Controllers\SearchController.php

<?php
namespace App\Http\Controllers;
use App\Doctor;
use Illuminate\Http\Request;

class SearchController extends SiteController
{
    public function __construct()
    {
        parent::__construct(new \App\Repositories\MenusRepository(new \App\Menu));
        $this->template = env('THEME').'.index_contents';
    }

    public function search(Request $request){
       if($request) {
            $posts = Doctor::search($request->get('search'))->paginate(1);
            $content = view(env('THEME').'.search_content')->with('posts', $posts)->render();
            $this->vars = array_add($this->vars, 'content', $content);
            return $this->renderOutput();
        }
        return abort(404);
    }

    public function autocomplete(){
        echo 'Ok!';
    }

}

В вьюхе:

<form action="{{ route('search') }}" method="get" role="form" class="search_form" >
                            {{--{{ csrf_field() }}--}}
                            <input type="search" name="search" class="search_input" autocomplete="off">
                            <input type="submit" class="search_button" value="">
                        </form>
                        <script>
                            $(document).ready(function() {

                                src = "{{ route('autocomplete') }}";
                                $(".search_input").autocomplete({
                                    source: function(request, response) {
                                        $.ajax({
                                            url: src,
                                            dataType: "json",
                                            data: {
                                                term : request.term
                                            },
                                            success: function(data) {
                                                response(data);
                                            }
                                        });
                                    }
                                });
                            });
                        </script>

Ошибок нет но и аякс запрос не отправляется(( Если не использовать аякс то автокомплит отлично работает.
Помогите кто в курсе в чем может быть причина.

#6 Re: Laravel 5.x » Не получается получить модель через связь » 06.04.2017 09:38:31

Illia пишет:

Создайте модель, diagnostic_centers_prices и в ней отношение

public function service_diagnostic_centers()
    {
        return $this->hasMany('App\Service_diagnostic_centers', 'service_id', 'id');
    }

И в запросе используйте ->with('method')

Например:

$result = Diagnostic_center::with('diagnostic_centers_prices.service_diagnostic_centers')->get();

Вообще отношения в моделях лучше называть сокращенно, например prices и services, тогда Ваш код выглядел бы приятнее

$result = Diagnostic_center::with('prices.services')->get();

Я использую метод load() для передачи свойств. Вот код промежуточной функции:

protected  function getDiagnostics(){

        $diagnostics = $this->diagnostics_rep->get('*');

        if($diagnostics){
            $diagnostics->load('diagnostic_centers_prices', 'service_diagnostic_centers');
        }

        return $diagnostics;
    }

Добавил отношение в модель Diagnostic_centers_price. Прописал так:

if($diagnostics){
            $diagnostics->load('diagnostic_centers_prices', 'diagnostic_centers_prices.service_diagnostic_centers');
        }

Получаю ошибку "Call to undefined method Illuminate\Database\Query\Builder::service_diagnostic_centers()"
И так:

if($diagnostics){
            $diagnostics->load('diagnostic_centers_prices', 'service_diagnostic_centers');
        }

Все равно пустая коллекция приходит.

#7 Re: Laravel 5.x » Фильтрация в категории » 05.04.2017 23:14:14

TrueKanonir пишет:

Не легче ли использовать dedicate query string filtering то сто Джефри Вей делал? Там пара методов  всего, и все четко пашет

Спасибо, буду документацию искать...)

#8 Laravel 5.x » Не получается получить модель через связь » 05.04.2017 23:11:54

lahno
Ответов: 2

Версия Laravel:5.2

Версия PHP: 5.6

Операционная система и её версия: Windows 10 x64

Задача, что должно происходить _в целом_, техническое задание:
Есть структура таблицы:

diagnostic_centers
    id - integer
    name - string

diagnostic_centers_prices
    diagnostic_centers_id - integer
    service_id - integer
    price - integer

service_diagnostic_centers
    id - integer
    group_id - integer
    name - string

group_service_diagnostic_centers
    id - integer
    name - string

Нужно получить коллекцию моделей с данными из всех таблиц через модель Diagnostic_center.
Делаю вот так:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Diagnostic_center extends Model
{
    //
    public function diagnostic_centers_prices()
    {
        return $this->hasMany('App\Diagnostic_centers_price', 'diagnostic_centers_id', 'id');
    }

    public function service_diagnostic_centers()
    {
        return $this->hasManyThrough(
            'App\Service_diagnostic_center', 'App\Diagnostic_centers_price',
            'service_id', 'id', 'id'
        );
    }


}

diagnostic_centers_prices получаю а вот service_diagnostic_centers - пустая коллекция.

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

#9 Laravel 5.x » Фильтрация в категории » 22.03.2017 14:22:01

lahno
Ответов: 2

Версия Laravel:5.2
Версия PHP: 5.6
Операционная система и её версия: Windows 10 x64

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

Код:
Routes:

Route::resource('clinics', 'ClinicsController',[
    'parameters' => [
        'clinics' => 'alias'
    ]
]);

app\Http\Controllers\ClinicsController.php

namespace App\Http\Controllers;

use App\Repositories\Actions_clinicsRepository;
use App\Repositories\ClinicsRepository;
use App\Repositories\DirectionsRepository;
use App\Repositories\BranchesRepository;
use Illuminate\Http\Request;

use App\Http\Requests;

use Config;

class ClinicsController extends SiteController
{
    protected $clinics_rep;
    protected $branches_rep;
    protected $directions_rep;
    protected $actions_clinics_rep;

    public function __construct(Actions_clinicsRepository $actions_clinics_rep, ClinicsRepository $clinics_rep, DirectionsRepository $directions_rep, BranchesRepository $branches_rep)
    {
        parent::__construct(new \App\Repositories\MenusRepository(new \App\Menu));

        $this->actions_clinics_rep = $actions_clinics_rep;
        $this->clinics_rep = $clinics_rep;
        $this->directions_rep = $directions_rep;
        $this->branches_rep = $branches_rep;

        $this->template = env('THEME').'.clinics';
    }

    public function index()
    {
        $clinics = $this->getClinics();
        $directions = $this->getDirections();
        $actions_clinic = $this->getActions();
        $total_actions_clinic = $this->getTotalActions();
        $actions_branches = $this->getActions_branches();

        $content = view(env('THEME').'.clinics_content')->with('clinics', $clinics)->with('directions', $directions)
            ->with('actions_clinic', $actions_clinic)->with('total_actions_clinic', $total_actions_clinic)
            ->with('actions_branches', $actions_branches)->render();
        $this->vars = array_add($this->vars, 'content', $content);

        return $this->renderOutput();
    }

    protected function getClinics(){
        $clinics = $this->clinics_rep->get(['id','name','alias','district','metro','short_description','image','rating','plus'],FALSE,'name',TRUE);
        if($clinics){
            $clinics->load('branches','actions');
        }
        return $clinics;
    }

    protected function getDirections(){
        $directions = $this->directions_rep->get('*',FALSE,'name');
        return $directions;
    }

    protected function getActions(){
        $actions = $this->actions_clinics_rep->get(['image','name','clinic_id','short_description'], Config::get('settings.category_actions'), 'created_at');
        if($actions){
            $actions->load('actions_clinic');
        }
        return $actions;

    }

    protected function getTotalActions(){
        $total_actions = $this->actions_clinics_rep->get(['id']);
        $total_actions = count($total_actions);
        return $total_actions;
    }

    protected function getActions_branches(){
        $actions_branches = $this->branches_rep->get('*');
        if($actions_branches){
            $actions_branches->load('actions_branches');
        }
        return $actions_branches;
    }

}

App\Repositories\Repository.php

namespace App\Repositories;
use Config;

abstract class Repository{

    protected $model = FALSE;

    public function get($select = '*', $take = FALSE, $sort = 'created_at', $pagination = FALSE){

        $builder = $this->model->select($select);

        if($sort == 'sort_order' or $sort == 'name'){
            $builder->orderBy($sort, 'asc');
        }else{
            $builder->orderBy($sort, 'desc');
        }

        if($pagination){
            return $this->check($builder->paginate(Config::get('settings.paginate')));
        }

        if($take){
            $builder->take($take);
        }

        return $this->check($builder->get());
    }

    protected function check($result){
        if($result->isEmpty()){
            return FALSE;
        }

        $result->transform(function ($item, $key){
            if(is_string($item->image) && is_object(json_decode($item->image)) && (json_last_error() == JSON_ERROR_NONE)) {
                $item->image = json_decode($item->image);
            }
            return $item;
        });

        return $result;
    }

}

app\Clinic.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Clinic extends Model
{
    //
    public function branches()
    {
        return $this->hasMany('App\Branche');
    }

    public function actions()
    {
        return $this->hasMany('App\Actions_clinic');
    }

}

Подвал раздела