@Eugene70

Почему передаётся пустой объект после изменения адреса роута?

Добрый день.
Есть роут Route::resource('/news', 'NewsController');, в котором обычные функции создания, редактирования и т.п. новостей. Но в процессе понадобилось изменить адрес на "/blog". Метод index отрабатывает как и раньше, а вот в метод show передаётся пустой объект.
C /news работает все хорошо. Не могу понять в чём проблема.
Модель News
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;

class News extends Model
{
    protected $fillable = [
        'title',
        'body',
        'published_at',
        'news_wall',
        'slug'
    ];
    protected $dates = ['published_at'];

    //protected $dateFormat = 'Y-m-d\TH:i:s';


    /**
     * Переопределение метода для генерации slug url
     *
     * @return string
     */
    public function getRouteKeyName() {
        return 'slug';
    }
    /**
     * Статья пренадлежит пользователю
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function user() {
        return $this->belongsTo('App/User');
    }
    /**
     * Выборка опубликованных статей
     *
     * @param $query
     */
    public function scopePublished($query) {
        $query->where('published_at', '<=', Carbon::now());
    }

    /**
     * Выборка статей в очередь на публикацию
     *
     * @param $query
     */
    public function scopeUnPublished($query){
        $query->where('published_at', '>', Carbon::now());
    }
    /**
     * Даёт аттрибут времени для статьи
     *
     * @param $date
     */
    public function setPublishedAtAttribute($date) {
        if($date === null) {
            $currentDate =  date('Y-m-d\TH:i:s');
            $this->attributes['published_at'] = Carbon::createFromFormat('Y-m-d\TH:i:s', $currentDate);
        }else {
            $this->attributes['published_at'] = Carbon::createFromFormat('Y-m-d\TH:i:s', $date)->format('Y-m-d\TH:i:s');
        }

    }
    /**
     * Красивое отображение даты и времени
     *
     * @return mixed
     */
    public function  getBeautifulDateAttribute() {
        Carbon::setLocale(config('app.locale'));
        if($this->published_at > Carbon::now()->subMonth()) {
            return $this->published_at->diffForHumans();
        }
        return $this->published_at->toDateTimeString('Y-m-d');
    }

}

NewsController
<?php

namespace App\Http\Controllers;

use App\News;
use Illuminate\Http\Request;
use App\Http\Requests\NewsRequest;
use Illuminate\Contracts\Filesystem\Factory;

use Auth;
use Image;

class NewsController extends Controller
{

    public function __construct(Factory $factory)
    {
        $this->factory = $factory;
    }
    /**
     * Отображение статей
     *
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function index() {
        $news = News::latest()
            ->published()
            ->paginate(10);

        return view('news.index', compact('news'));
    }
    /**
     * Отображение отдельной статьи
     *
     * @param News $news
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function show(News $news) {
        return view('news.show', compact('news'));
    }
    /**
     * Отображение формы создания статей
     *
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function create() {
        return view('news.create');
    }
    /**
     * Создает статью
     *
     * @param Request $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function store(NewsRequest $request) {
        $input = $this->imageArticleRequest($request);
        Auth::user()->news()->create($input);

        return redirect('news');
    }
    /**
     * Отображение формы редактирования запмси
     *
     * @param $id
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function edit($id){
        $news = News::findOrFail($id);
        return view('news.edit', compact('news'));
    }
    /**
     * Обновляет статью и удаляет старое изображение
     *
     * @param $id
     * @param NewsRequest $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function update($id, NewsRequest $request) {
        $news = News::findOrFail($id);
        $input = $this->imageArticleRequest($request);;
        if($input !== null) {
            $old_image = $news->news_wall;
            $disk = $this->factory->disk('images');
            $disk->delete('/newsImages/' . $old_image);
            $news->update($input);
        }else {
            $news->update($request->all());
        }

        return redirect('news/'.$news->slug);
    }
    /**
     * Удаление записи
     * @param $id - id записи
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function destroy($id) {
        $news = News::findOrFail($id);
        $oldImage = $news->news_wall;
        $disk = $this->factory->disk('images');
        $disk->delete('/newsImages/' . $oldImage);
        $news->delete();

        return redirect('news');
    }
    /**
     * Функция обрезки и загрузки изображения для статьи, генерации слага
     *
     * @param $request
     * @return array
     */
    protected function imageArticleRequest($request) {
        if ($request->hasFile('news_wall')) {
            $image = $request->file('news_wall');
            $imageName = time() . "." . $image->getClientOriginalExtension();
            $savePath = public_path('images/uploads/newsImages/' . $imageName);
            Image::make($image)
                ->save($savePath);
            $input = $request->all();
            $input = array_except($input, 'pathName');
            $input['news_wall'] = $imageName;
            $title = $input['title'];
            $input['slug'] = str_slug($title);
            return $input;
        }
    }


}
  • Вопрос задан
  • 253 просмотра
Решения вопроса 1
neuotq
@neuotq
Прокрастинация
Все просто, ресурсный контроллеры создают роуты с переда автоматически на основе базового имени роута, таким образом у вас теперь:
Route::resource('/blog', 'NewsController'); и таким образом ваш ресурсный контроллер ожидает переменную одну, а получает другую. Вообще у тебя должны быть написано Route::resource('blogs', 'NewsController'); и таким образом в параметры уйдет переменная blog с объектом. Но так как метод у тебя уже написан $news (да не удачно, как же единственное число, хех. Впрочем сам я такое попадался).
Так, короче говоря в web :
Route::resource('blog', 'NewsController')->parameters([
    'blog' => 'news'
]);

Ну и в параметрах методов контроллера замени везде "$id" на "News $news", хотя в целом у тебя уже не ресурсный контроллер, например метод store. Так что возможно тебе лучше расписать все в ручную. В целом изначально ресурсные контроллеры подходя либо под api логику работы, когда ты имеешь дело с Моделью/Сущностью как с ресурсом и тебе нужны стандартные методы, либо многие используют в своих CRUD логиках, но опят таки только если логика без дополнительных усложнений и переплетений как у тебя. Де факто у тебя не ресурсный контроллер и я настоятельно рекомендую расписать его в ручную.
PS еще для отладки роутов отлично подходит команда php artisan route:list будет видны все роуты которые ларавел генерирует, с соответствующими параметрами переменными.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы