Laravel по-русски

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

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

#1 Re: Laravel 5.x » redirect в роутах на пока еще неизвестный экшн » 15.01.2018 14:13:31

Я не разбирался досконально, но происходит примерно следующее.
Когда мы вызываем хелпер action(Controller@Method), он (хелпер) создает объект Illuminate\Routing\UrlGenerator (через хелпер app) с вызовом метода action()

    // это хелпер action
    function action($name, $parameters = [], $absolute = true)
    {
        return app('url')->action($name, $parameters, $absolute);
    }

Метод action() UrlGenerator-а лезет к внедренному в routes объекту Illuminate\Routing\RouteCollection и вызывает метод getByAction ().

    // это класс UrlGenerator
    public function action($action, $parameters = [], $absolute = true)
    {
        if (is_null($route = $this->routes->getByAction($action = $this->formatAction($action)))) {
            throw new InvalidArgumentException("Action {$action} not defined.");
        }
        return $this->toRoute($route, $parameters, $absolute);
    }

Уже становится понятно, почему не работает) Но продолжая - метод getByAction() RouteCollection-а проверяет запрошенный роут по списку роутов, если находит - возвращает его в UrlGenerator для дальшейшего перехода, если нет - возвращает null, и мы ловим нашу ошибку из UrlGenerator-а.

    // это класс RouteCollection
    public function getByAction($action)
    {
    return isset($this->actionList[$action]) ? $this->actionList[$action] : null;
    }

Если говорить проще, то хелпер action() попадает в экшен контроллера через роут. А так как конкретно этого роута у нас нет (только "универсальный") - он и выдает ошибку.

Наш рабочий вариант App::call() чуть сложнее и более запутан. Кстати, вместо фасада использовать хелпер app()->call(). Я до сих пор до конца не разобрался smile Из того, что находил в коде - хелпер\фасад создает контейнер с объектом Application, вызывается метод родительского класса Container - сall()

    public function call($callback, array $parameters = [], $defaultMethod = null)
    {   
        return BoundMethod::call($this, $callback, $parameters, $defaultMethod);
    }

После чего в Illuminate\Container\BoundMethod методом Call() (21 строка) уже и вызывается наш запрошенный контроллер с методом. Как конкретно вызывается - до этого как раз не докопал, там начинается какой-то хард c коллбеками)

#2 Re: Laravel 5.x » redirect в роутах на пока еще неизвестный экшн » 15.01.2018 02:07:53

Имхо - это занятие чисто для саморазвития, делать так на реальных проектах все-таки не надо ))

Но как эксперимент - опробуйте это решение, должно работать

Route::get('/seeds/{var}', function ($var) {
	return App::call('App\Http\Controllers\MakeSeedingController@' . $var);
});

#3 Re: Laravel 5.x » redirect в роутах на пока еще неизвестный экшн » 15.01.2018 01:52:03

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

#4 Re: Laravel 5.x » redirect в роутах на пока еще неизвестный экшн » 15.01.2018 01:33:47

Какой url забиваете? Простой роут (внизу) экшн видит или такую же ошибку возвращает?

Route::get('make','MakeSeedingController@index');

#5 Re: Laravel 5.x » redirect в роутах на пока еще неизвестный экшн » 15.01.2018 00:50:05

Вот по такой аналогии можно делать универсальные роуты. Нужно ли - вопрос. Вариант нужно допиливать, чтобы он отдавать 404 ошибку если ввели неверный метод. Ничего сложного, но говнокодить try-catch или как-то по иному в роутах я не берусь smile
Но как по мне, это вообще не очень хорошая практика. Возможно есть более грамотный способ.

Route::get('/seeds/{var}', function ($var) {
	return redirect()->action('GamesController@' . $var);
});

Насчет вашего примера - проверьте еще раз контроллер и метод.

#6 Re: Laravel 5.x » Роутинг /mylink/id => id='aaa/bbb/ccc' » 14.01.2018 18:24:40

Роут куда будет отправлять? На контроллер? На один метод или на разные?

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

// Задаем паттерн для параметра роута (переменной) link - в данном случае английские буквы и цифры в любом количестве, а также слэш для имитации url 
Route::pattern('link', '[a-z0-9/]*');
// Собственно в роут включаем эту переменную. Конкретном в строчке ниже для всех url типа mylink/* будет вызываться метод Index для MyController
Route::get('mylink/{link}', 'MyController@index');

Если на разные методы - то надо еще покрутить, или задать себе вопрос о целесообразности такой вложенности роута.

#7 Re: Laravel 5.x » Помогите построить отношение Eloquent » 14.01.2018 05:26:48

Или я не понимаю структуру таблиц, или ты делаешь что-то не так. Pivot table (сводную таблицу) чаще всего создают для связи двух таблиц отношением "Многие ко Многим". На крайняк можно, конечно, и другие отношения внедрить через пивот, но смысла в этом в общем случае нет, да и мануал подсказывает другие способы. Также сводной таблицей можно связать записи в одной таблице отношением многие ко многим (например, связать юзеров дружескими узами).
У тебя же сводная таблица связывает таблицу (properties) со своим же полем (categories), я правильно все увидел? Или на скрине результат селекта с джоином? smile Ну и сериализованные массивы хранить в базе -  так себе практика. От всего этого возникают вопросы вообще не только к тому, как это реализовать, а и к тому, что ты хочешь вообще получить в итоге и откуда это все тут взялось smile

В идеале напиши что там за массив хранится и какую логику хочешь выстроить. Почему в названии темы ты хочешь выстроить "отношение Eloquent", а структура базы говорит нам о совсем другом - что никаких двух моделей здесь не видать. Ты же не сохраняешь ОРМ модель в поле другой ОРМ модели? smile

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

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