I have a project on Laravel 5.8. It's internet-market with categories, brands and products. I used in my controllers a variable from model:
route:
Route::prefix('categories')->get('/{category}', 'ProductsController#openCategory')->name('openCategory');
model:
class Category extends Model
{
public function products()
{
return $this->hasMany(Product::class);
}
public function getRouteKeyName()
{
return 'category_alias';
}
}
controller-method:
public function openCategory(Category $category = null)
{
$allInfo = $this->getAllInfo();
$categories = $this->getCategories();
$brands = $this->getBrands();
return view("pages.category", compact('allInfo','category', 'categories', 'brands'));
}
I don't use relation by ID, I use relation by 'category_alias'. But if I write category name with error, I get message - OPPS! We Couldn’t Find this Page
Uh... So it looks like you brock something. The page you are looking for has up and Vanished. Why? But if I use relation by ID, I get page 404 - it's success for me.
By defining the route with ->get('/{category}' and typehinting on the controller, Category $category you are telling Laravel that you want it to resolve the category for you.
This is handled by the service container as described at https://laravel.com/docs/master/container#introduction
If you provide a value which doesn't resolve to the id for a category in the database, the service container will be be unable to load anything. Laravel responds to those scenarios by returning the 404.
Related
I am getting a "404 | Not Found" error when i try to access a specific item from my database. The items with the specific ID's do exist in the database, but i am not even sure if that even has any influence on the problem.
My routing looks likes this:
Route::prefix('departments')->group(function() {
Route::get('/{id}', [DepartmentController::class, 'showDepartment']);
});
And the related controller looks like this:
public function showDepartment() {
return '';
}
}
I haven't yet finished the function. I just wanted to check if the routing even worked by returning an empty string.
So what am i doing wrong? Is it the routing or the controller?
According to the Laravel documentation, you have to define the parameter in the route then use it in the controller as a parameter.
in your controller:
public function showDepartment($id) {
return 'Hello';
}
The id is not bound to any model to fetch from the database to do that you can use Laravel route model binding
for example when you have a model named Department you write your route like this:
Route::get('/{department}', [DepartmentController::class, 'showDepartment']);
and in the controller:
public function showDepartment(Department $department) {
return 'Hello from depratment';
}
When your department exists it returns the response otherwise return 404.
You may need a Department model class. Then you can find the item from database by id $department = Department::findOrFail($id);
you are send parameter in route and this function without any parameter
route :
Route::prefix('departments')->group(function() {
Route::get('/{id}', [DepartmentController::class, 'showDepartment']);
});
your function in controller should be
public function showDepartment($id) {
$department = Department::findOrFail($id);
}
}
I have the two following models in one to many relationship:
Category.php
public function post()
{
return $this->hasMany('App\Category', 'category_id');
}
And Post.php
public function category()
{
return $this->belongsTo('App\Post', 'category_id');
}
I delete thee category that has few blog post under it.
Open the blog post whose category is deleted
Gets error as the category doesn't exist anymore
What is the best way to delete the category without causing the error ? Should I set the category_id of post to null while deleting their category ?
Use withDefault for if any category doesn't exist it'll give you null.
Category.php
public function post()
{
return $this->hasMany('App\Post', 'category_id')->withDefault();
}
Post.php
public function category()
{
return $this->belongsTo('App\Category', 'category_id')->withDefault();
}
Maybe this is gonna be the late answer but I will answer for Google searches anyway.
You can handle relationship cascading on the database If you don't want any null error about deleting the models on your project. Write this code to your project table migration.
$table->bigInteger('category_id')->unsigned();
$table->foreign('category_id')->references('id')
->on('categories')->onDelete('cascade');
Im trying to call a list os posts based on a category, but it isnt working, is giving me the error:Non-static method App\Category::posts() should not be called statically, assuming $this from incompatible context.
I already tried calling from both sides, going threw the post model methdos or categories, but same error message. Can figure out what im doing wrong.
Database:
Posts:
-id;
-title;
-text;
Categories:
-id;
-name;
-internal_name;
category_post:
-id;
-post_id;
-category_id
Controller:
public function categoryPostList($category)
{
$category = Category::posts()->where('internal_name',$category)->first();
$posts = Post::categories()->where('category_id',$category->id)->get();
dd($posts)
}
Model Post:
class Post extends Model
{
public function categories()
{
return $this->belongsToMany(Category::class);
}
}
Model Category:
class Category extends Model
{
public function posts()
{
return $this->belongsTo('App\Post');
}
}
First of all if relationship is many to many (you're using pivot table) your relation should be belongsToMany(), but not belongsTo().
To load relation You should use with() method. For example, if you want to load one category with all it's posts:
Post::where('category_id', $category->id)->with('categories')->first();
You can use whereHas as:
$category = Category::where('internal_name',$category)->first();
$posts = Post::whereHas('categories', function($q) use($category) {
$q->where('category_id',$category->id);
})->get();
Or
$category = Category::where('internal_name',$category)->first();
$posts = $category->posts;
The whereHas method is used to put "where" conditions on your has
queries.
To start, my models look something like this:
class Post extends Eloquent {
public function url() {
return $this->belongsTo('Url', 'url_id');
}
}
class Url extends Eloquent {
public function category() {
return $this->belongsTo('Category', 'category_id');
}
}
The relationship that is intended is that a Post has a Url and a Url has a Category, so a Post should implicitly have a Category. I am trying to write an Eloquent query to filter posts by category_id. I have a variable that is being passed into a GET route that represents the category_id and want to filter all posts by the category_id that is passed to that route.
Any help is appreciated.
Thanks in advance.
When defining an inverse relation in Eloquent, do you have to name your dynamic property the same as your related model?
class Book extends Eloquent {
public function author()
{
return $this->belongsTo('Author');
}
}
$books = Book::all()
foreach ($books as $book) {
echo $book->author->firstname;
}
In the above example, do I have to call this method author or can I name it something else? I tried to name it to something else (just out of curiosity) but it then returns null hence the errors "Trying to get property of non-object".
EDIT: I got it to work by passing the foreign key to belongsTo, like this:
class Book extends Eloquent {
public function daauthor()
{
return $this->belongsTo('Author', 'author_id');
}
}
$book = Book::find(55);
dd($book->daauthor);
Can someone explain why?
The method belongsTo tries to determine the attribute which links to the Author model. To accomplish this Laravel uses the function name of the caller.
So in your code Laravel sees the daauthor function and tries to use the attribute daauthor_id in the books table to fully your request. As your books table does not have this attribute it fails.
By setting the $foreignKey on the method you can override the default behaviour:
public function daauthor()
{
return $this->belongsTo('Author', 'author_id');
}
For more details check out the source code of \Illuminate\Database\Eloquent\Model.