Let say I have product under parent->child one and another product under parent->child one->child one child all i can get is last category name like:
child one and child one child but parent names before them i cannot get.
Code
Category model:
public function categories()
{
return $this->hasMany(Category::class);
}
public function childs() {
return $this->hasMany(Category::class,'category_id','id') ;
}
public function products(){
return $this->hasMany(Product::class);
}
Product model:
public function category(){
return $this->belongsTo(Category::class);
}
And I store category id in products table, column named category_id.
PS: in this column i store last category id, like if i have:
parent->child one i store child one id in there.
UPDATE
Base on answers I've made some changes in my category model and by code below I've tried to get my product category levels:
#if($product->category->isParent())
{{ucfirst($product->category->title)}} </br>
#else
{{ucfirst($product->category->parent->title)}} > {{ucfirst($product->category->title)}} </br>
#endif
Issue
Issue by code above is: if my product is in third level (or more) I only get parent of last category and not all the way top. EXAMPLE
my product is in : Laptop->HP->PAVILION all I get is HP->PAVILION cannot get laptop category.
I'm not sure if I understand good but...
Into Category Model
public function parent()
{
return $this->belongsTo(Category::class,'category_id');
}
public function childs() {
return $this->hasMany(Category::class);
}
public function isParent()
{
return !$this->category_id ? true : false; // if category_id is null => is a Parent Category
}
You can do $category->isParent() to know if is a Parent or not.
If is parent category you can do $category->childs to get all sub categories.
If is not a parent you can do $category->parent to get parent Category.
From your code it seems you are defining wrong relationships between the classes. Please refer this link https://laravel.com/docs/5.6/eloquent-relationships#one-to-many laravel documentation for the same.
Also if you want to call a particular child through a parent model, one way to call is as below:
$children = App\Category::find(1)->childs;
Because you have defined your relationship function with name "childs" you have to use same name to access the children for that class.
Related
I'm putting together a blog in Laravel 8. I can get the slug for categories, sub-categories, sub-subcategories, and sub-sub sub-categories independently, but for some reason, the sub-categories and the sub-sub-categories can't get the slug of the parent category id. I'm sure I've built the appropriate relationship with the Category model like so
public function subsubcatheader()
{
return $this->hasMany(HairBlogSubSubCategory::class, 'category_id', 'id');
}
public function subsubsubcatheader()
{
return $this->hasMany(HairBlogSubSubSubCategory::class, 'category_id', 'id');
}
And in my Sub Category Model, the relationship is set up like
public function catsubliner()
{
return $this->belongsTo(HairBlogCategory::class,'category_id','id');
}
In the blade, I'm using the URL::to method like this.
{{ URL::to('/natural-hair-blogs/s').'/'.
$subcategory->catsubliner->slug.'/'.$subcategory->slug }}
It correctly gets the parent category slug, but I get a page not found error. Any help is much obliged.
i have laravel models
Category: id,name
public function posts(){
return $this->hasMany(PostCategory::class,'category_id','id');
}
PostCategory : post_id, category_id
public function post(){
return $this->belongsTo(Post::class,'post_id');
}
POST: id, ..so on
public function solutions(){
return $this->hasMany(PostSolution::class,'post_id','id');
}
I need to get count of all posts fall under a category and also solutions under one category.. there is no direct relation of category and solution so how to get count of solutions in one category.
$categories = Category::withCount('posts')->get();
I think use hasManyThrough relation
// Category Class
public function solutions()
{
return $this->hasManyThrough(PostSolution::class, Post::class);
}
// Then get the data in the same old manner
$categories = Category::->withCount('posts')->get();
I hope this will help
Hi guys i wish to create a custom method on my Category Model but i need to create some conditionals with it.
table post:
- id;
- category_id
-name...
table Category:
- id
- parent_id
- name
Imagin that i have a post, and in this post there is a category called SomeSubcategoryName, i my posts table i have a column called category_id.
When i call the post record i have a relation with the Category Model, but i wish to have in my Category Model a method called masterCategory, where i give the mster category by checking if the parent_id is null or not, in case that the record have a parent_id of null great, i return the record but if is not i need to use the parent_id value and search on the Model category column id for the record and return the result.
Imagine this scenario:
$post = Post::find(2);
//this call should return the main category and not the subcategory info.
$post->masterCategory();
In your category model define a relationship on its self:
public function masterCategory()
{
return $this->belongsTo(App\Category::class, 'parent_id', 'id');
}
Eager load the relationships on your Post when you query it:
$post = Post::with(['category', 'category.masterCategory'])->firstOrFail($id);
Access it like this:
$post->category->masterCategory; // will be the mastery category or null
Otherwise us:
$post->category;
Don't over complicate it.
In your Category model you should have something like this
public function master()
{
return $this->belongsTo(Category::class, 'parent_id');
}
public function isMaster()
{
if($this->parent_id)
return false;
else
return true;
}
Now you can check that post's category is master or not :
if($post->category->isMaster())
....
The second way is using relations and eloquent
$post = Post::with(['category', 'category.master'])->first($id);
I have two tables: categories and products.
In products table migration I have defined this:
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
so when a category is deleted, all products from that category is deleted.
Model for category contains:
public function product() {
return $this->hasMany('App\Product');
}
Model for product contains:
public function category() {
return $this->belongsTo('App\Category');
}
Category and product model contains two methods for saving and deleting photos, that are stored on file system.
Method for deleting the photo attached to category or photo:
public static function deleteImage($id) {
File::deleteDirectory(public_path() . self::$imagesPath . $id);
}
This method is called by overriding destroy function on product or category model:
public static function destroy($id) {
self::deleteImage($id);
parent::destroy($id);
}
So, the problem is if I delete a category, I want to delete products images too, beside records in products table, but products images remain on the file system. Only category images are deleted from the file system.
I put an dd('message') in destroy function in product model, but seems that the destroy method, on product model is not called when a category is deleted.
How can I delete product images, when a category is deleted?
Since MySQL is the one deleting the products, Eloquent has no way to know about it.
You'll have to do it in the category model's deleting event:
class Category extends Eloquent {
public static function boot()
{
static::deleting(function()
{
foreach ($this->products as $product)
{
$product->deleteImage($product->id);
}
});
}
}
I am setting up several Models an want to know the correct approach to table structure and Model relationships.
Let's assume we have a shop containing products, each with properties size and color.
Table products
id
size_id
color_id
price
Table sizes
id
name
Table colors
id
name
Models
class Product extends Eloquent {
public function size() {
return $this->hasOne('Size', 'id');
}
public function color() {
return $this->hasOne('Color', 'id');
}
}
class Size extends Eloquent {
public function products() {
return $this->belongsTo('Product', 'size_id');
}
}
class Color extends Eloquent {
public function products() {
return $this->belongsTo('Product', 'color_id');
}
}
This way I can easily echo the color/size of a product using {{ Product->size['name'] }}. Also, I want to pass Eloquent the size's foreign key size.id like Product::where('size_id', '5') rather than its name size.name.
Problem: Doing $products = Product::has('size', '=', '5')->get() does not give me any results, yet doing $products = Product::where('size_id', '5')->get() does.
I am pretty confused, what went wrong?
I think that the problem is that your ::has() method is looking for products with exactly 5 different sizes on each specific product, which would assume that you would be using $this->hasMany('Size') in your Product model. Where as the ::where() method is returning results where the size of the product is 5.
In the documentation they use an example of comments. A post will have a list of comments. You can find posts that have at least one comment (ie. Post::has('comments')->get()) or you can find posts that have more than 3 comments (ie. Post::has('comments', '>=', '3')->get()).
http://laravel.com/docs/eloquent#querying-relations