Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Я не разбирался досконально, но происходит примерно следующее.
Когда мы вызываем хелпер 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(). Я до сих пор до конца не разобрался Из того, что находил в коде - хелпер\фасад создает контейнер с объектом Application, вызывается метод родительского класса Container - сall()
public function call($callback, array $parameters = [], $defaultMethod = null)
{
return BoundMethod::call($this, $callback, $parameters, $defaultMethod);
}
После чего в Illuminate\Container\BoundMethod методом Call() (21 строка) уже и вызывается наш запрошенный контроллер с методом. Как конкретно вызывается - до этого как раз не докопал, там начинается какой-то хард c коллбеками)
Имхо - это занятие чисто для саморазвития, делать так на реальных проектах все-таки не надо ))
Но как эксперимент - опробуйте это решение, должно работать
Route::get('/seeds/{var}', function ($var) {
return App::call('App\Http\Controllers\MakeSeedingController@' . $var);
});
Понял в чем ошибка - он пытается редиректить на экшн, для которого не прописан роут. Для теста пропишите например простой роут на индекс и снизу наш с замыканием - замыкание должно работать Или механизмы другие - но суть ошибки в этом.
Поэтому вариант, предложенный мной выше, не годится, сейчас придумаю новое что-нибудь.
Какой url забиваете? Простой роут (внизу) экшн видит или такую же ошибку возвращает?
Route::get('make','MakeSeedingController@index');
Вот по такой аналогии можно делать универсальные роуты. Нужно ли - вопрос. Вариант нужно допиливать, чтобы он отдавать 404 ошибку если ввели неверный метод. Ничего сложного, но говнокодить try-catch или как-то по иному в роутах я не берусь
Но как по мне, это вообще не очень хорошая практика. Возможно есть более грамотный способ.
Route::get('/seeds/{var}', function ($var) {
return redirect()->action('GamesController@' . $var);
});
Насчет вашего примера - проверьте еще раз контроллер и метод.
Роут куда будет отправлять? На контроллер? На один метод или на разные?
Если на один метод - придумал такой способ, выглядит значительно более органичным. После первого слэша получается эдакий псевдороутинг, и можно писать то, что душе угодно - все улетит в один роут Регулярку подкрутить в нужном направлении и будет делать то, что надо.
// Задаем паттерн для параметра роута (переменной) link - в данном случае английские буквы и цифры в любом количестве, а также слэш для имитации url
Route::pattern('link', '[a-z0-9/]*');
// Собственно в роут включаем эту переменную. Конкретном в строчке ниже для всех url типа mylink/* будет вызываться метод Index для MyController
Route::get('mylink/{link}', 'MyController@index');
Если на разные методы - то надо еще покрутить, или задать себе вопрос о целесообразности такой вложенности роута.
Или я не понимаю структуру таблиц, или ты делаешь что-то не так. Pivot table (сводную таблицу) чаще всего создают для связи двух таблиц отношением "Многие ко Многим". На крайняк можно, конечно, и другие отношения внедрить через пивот, но смысла в этом в общем случае нет, да и мануал подсказывает другие способы. Также сводной таблицей можно связать записи в одной таблице отношением многие ко многим (например, связать юзеров дружескими узами).
У тебя же сводная таблица связывает таблицу (properties) со своим же полем (categories), я правильно все увидел? Или на скрине результат селекта с джоином? Ну и сериализованные массивы хранить в базе - так себе практика. От всего этого возникают вопросы вообще не только к тому, как это реализовать, а и к тому, что ты хочешь вообще получить в итоге и откуда это все тут взялось
В идеале напиши что там за массив хранится и какую логику хочешь выстроить. Почему в названии темы ты хочешь выстроить "отношение Eloquent", а структура базы говорит нам о совсем другом - что никаких двух моделей здесь не видать. Ты же не сохраняешь ОРМ модель в поле другой ОРМ модели?
Ну и в догонку - вот по тому, что я вижу, реально написать только кривой SQL запрос. И то с большими "зачем это все" по пути.