can you please describe whats wrong with my code below. Their is an error when I click Update button and getting id of update Request. What I want to do is to update category name and tag with a post (post_tag i.e belongstoMany) And it says "Trying to get property of non-object.
//class Post extends Model
public function category()
{
return $this->belongsTo('App\Category');
}
public function tags()
{
return $this->belongsToMany('App\Tag');
}
// class Tag extends Model
public function posts()
{
return $this->belongsToMany('App\Post');
}
// class Category extends Model
protected $table = 'categories';
public function posts()
{
return $this->hasMany('App\Post');
}
// PostController
public function edit($id)
{
// find the post in the database and save as a var
$post = Post::find($id);
$categories = Category::with('posts')->get();
$cats = array();
foreach ($categories as $category) {
$cats[$category->id] = $category->name;
}
$tags = Tag::with('posts')->get();
$tags2 = array();
foreach ($tags as $tag) {
$tags2[$tag->id] = $tag->name;
}
// return the view and pass in the var we previously created
return view('backend.pages.posts.edit')->withPost($post)->withCategories($cats)->withTags($tags2);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
// Validate the data
$post = Post::find($id);
if ($request->input('slug') == $post->slug) {
$this->validate($request, array(
'title' => 'required|max:255',
'category_id' => 'required|integer',
'body' => 'required'
));
} else {
$this->validate($request, array(
'title' => 'required|max:255',
'slug' => 'required|alpha_dash|min:5|max:255|unique:posts,slug',
'category_id' => 'required|integer',
'body' => 'required'
));
}
// Save the data to the database
$post = Post::find($id)->first();
$post->title = $request->input('title');
$post->slug = $request->input('slug');
$post->category_id = $request->input('category_id');
$post->body = $request->input('body');
if (isset($request->tags)) {
$post->tags()->sync($request->tags);
} else {
$post->tags()->sync(array());
}
$post->save();
notify()->success("The blog post was successfully updated!", 'Success');
return redirect()->route('app.posts.show', $post->id);
// return back();
}
//edit.blade.php file
// An error appears in select option finding an id which is a non-object
// A 2 line code below which is inside of form POST METHOD {{ route('app.posts.update', $post->id) }} //
<select class="form-control" name="category_id" class="form-control @error('category_id') is-invalid @enderror" required>
@foreach($categories as $key=>$category)
<option value="{{ $category>id }}" @isset($post) {{ $post->category->id == $category->id ? 'selected' : '' }} @endisset>{{ $category->name}}</option>
@endforeach
// Same error below tag name cannot get property
<select class="form-control select2-multi" id="tags" name="tags[]" multiple>
@foreach($tags as $key=>$tag)
<option value="{{ $tag }}" {{ old('tags[]', $post->tag)->contains($tag) ? 'selected' : '' }}>{{ $tag->name }}</option>
@endforeach
</select>
//End form
I got it. the $categories
variable the you pass to the view is an array, with keys are category ids and values are category names. In your view, inside the loop, that $category
variable is a string, but you try to access that as an object ($category->id
) and get the error.
SOLUTION 1:
You can update your code like this:
<select class="form-control" name="category_id" class="form-control @error('category_id') is-invalid @enderror" required>
@foreach($categories as $categoryId => $categoryName)
<option value="{{ $categoryId }}" @isset($post) {{ $post->category->id == $categoryId ? 'selected' : '' }} @endisset>{{$categoryName}}</option>
@endforeach
<select class="form-control select2-multi" id="tags" name="tags[]" multiple>
@foreach($tags as $tagId => $tagName)
<option value="{{ $tagId }}" {{ old('tags[]', $post->tags)->contains($tagId) ? 'selected' : '' }}>{{ $tagName }}</option>
@endforeach
</select>
SOLUTION 2:
I see that in the controller action, you transform you categories and tags to arrays, which is not necessary. Just get those from the database and pass to the view.
public function edit($id)
{
// find the post in the database and save as a var
$post = Post::find($id);
$categories = Category::with('posts')->get();
$tags = Tag::with('posts')->get();
return view('backend.pages.posts.edit', [
'post' => $post,
'categories' => $categories,
'tags' => $tags,
]);
// Or you can even write: return view('backend.pages.posts.edit', compact('post', 'categories', 'tags'));
}
Then in your view:
<select class="form-control" name="category_id" class="form-control @error('category_id') is-invalid @enderror" required>
@foreach($categories as $category)
<option value="{{ $category->id }}" @isset($post) {{ $post->category->id == $category->id ? 'selected' : '' }} @endisset>{{$category->name}}</option>
@endforeach
<select class="form-control select2-multi" id="tags" name="tags[]" multiple>
@foreach($tags as $tag)
<option value="{{ $tag->id }}" {{ old('tags[]', $post->tags)->contains($tag->id) ? 'selected' : '' }}>{{ $tag->name }}</option>
@endforeach
</select>