I have some tables:
category:
id: 1 title: Shirt
id: 2 title: Pant
id: 3 title: Hat
product:
... (product has some columns and 1 col is category_id)
And what I want to display in view is:
1. 5 newest posts for all categories
2. 5 newest posts for each category
Basically, it'll look like:
--* Title :All *--
5 Newest posts
--* Title :Shirt *--
5 Newest posts which category_id :1
--* Title :Pant*--
5 Newest posts which category_id :2
--* Title :Hat *--
5 Newest posts which category_id :3
Any advices, I've searched on google but didn't find the answer :((
Since you have two tables, you'd create two models, one for category and one for product. You can do this by running php artisan make:model Category and php artisan make:model Product
Now you have these models in your App/ folder.
Add the following to your category model in App\Category
public function products()
{
return $this->hasMany('\App\Product', 'category_id', 'id');
}
Go on to the controller that wants to process these data and add at the top
use App\Category;
use App\Product;
5 newest posts for all categories
$product = Product::take(5)->orderBy('id', 'desc')->get();
5 newest posts for each category
$categories = Category::get();
foreach ($Categories as $Category) {
$products[$Category->name] = $Category->products()->take(5)->orderBy('id', 'desc')->get();
}
Now to pass this on to the view, i like using a "$data" array, the contents of this array can be accessed directly in the views once passed like so
$data = array();
$data['all_products'] = $product;
$data['category_products'] = $products;
This can then be passed on as
return View('products.detail', $data);
where products.detail is your view
You can now loop through these data in your view as
--* Title :All *--
#foreach($all_products as $product)
{{$product->name}}
#endforeach
If you have category model like this:
class Category extends Model
{
public function posts()
{
return $this->hasMany('\App\Post', 'category_id', 'id');
}
}
You can take 5 Latest post's of every category easily:
$Categories = Category::get();
foreach ($Categories as $Category) {
$Posts = $Category->posts()->take(5)->orderBy('id', 'desc')->get(); // Get 5 Posts
}
Related
I want to display related item which is in same category.
Here is my 3 table structure
food item table
:
"food_item_id",
"name" ,
"image" ,
food item category table :
"food_item_category_id"
"name"
pivot table
id,
food_item_id
food_item_category_id
FooItem model:
public function foodItemCategory() {
return $this->belongsToMany(FoodItemCategory::class, 'food_items_have_categories', 'food_item_id', 'food_item_category_id')
->withPivot('food_item_id', 'food_item_category_id')
->withTimestamps();
}
Food Category Model:
public function foodItem() {
return $this->belongsToMany(FoodItem::class, 'food_items_have_categories', 'food_item_category_id', 'food_item_id')
->withPivot('food_item_id', 'food_item_category_id')
->withTimestamps();
}
I want to get all food items from a specific category. Suppose a user clicks on a food item which Id is 1 and It is belongs to category ID 2. Now I want to show more food items which is in the category ID 2. I want to display that in my view blade.
Now, how can I display the related products in view which is in the same category?
As your relation is many to many, you can do this:
$food = FoodItem::find(1);
$categories = $food->foodItemCategory;
$items = [];
foreach($categories as $category) {
$items[$category->id] = $category->foodItem;
}
then you can pass $items to your blade template.
I have a 1 category and subcategory table
table name: categories
another table is posts posts table
when click on google app script all post regarding category and sub category of google app script will show enter image description here
my controller code is and name of controller is bloglistController
$posts = post::where('category_id', $id)->paginate(7);
but this code shows only category id post I want post of both category and sub category
For category model
public function post()
{
return $this->hasMany(Post::class, 'parent_id', 'category_id');
}
In your controller
$category = Category::where('parent_id',1)->first();
$post = $category->post;
I have three models
Project
Category
Drawing
The relationship between them is as follows
Drawing belongs to a category
Drawing also belongs to a project
Drawing table:
id
name
project_id
category_id
Project Table :
id
name
Category Table :
id
name
I want to print all the drawings of a particular project grouped by category name like so :
CATEGORY X
* Drawing 1
* Drawing 2
CATEGORY Y
* Drawing 3
* Drawing 4
I do not want to print a category if there is no drawing for this particular project in it.
this is what im stuck at :
Project->drawings()->groupBy('category_id');
Thank you in advance
To get the output you want, it'd be easier to come at the problem from the direction of categories.
The following will find all categories, with drawings belonging to the specified $projectId, but only those categories that actually have one or more drawings.
$projectId = 123;
$projectScope = function ($query) use ($projectId) {
return $query->where('project_id', $projectId)
});
$categories = Category::with(['drawings' => $projectScope])
->whereHas('drawings', $projectScope)
->get();
You can do it like
$categories = Category::whereIn('id',$project->drawings()
->groupBy('category_id')
->pluck('category_id')
)->get();
Now, Iterate over $categories like
#foreach($categories as $category)
// display category name as {{$category->name}}
#foreach($category->drawings() as $drawing)
// display drawings as {{$drawing->name}}
#endforeach
#endfoeach
Hope you understand.
I am trying to display the product listing on listing page of the product. Each product has category.My table structure
categories
id name description
1 Cat1 Category 1
2 Cat2 Category 2
This is the category table having id name and description
products
id name description category_id
1 pro1 product 1 1
2 pro2 product 2 2
This is the product table having category_id.
Product Model
public function categories() {
return $this->belongsTo("App\Category");
}
This is the product model where the products are belongs to category
Category Model
public function products() {
return $this->hasMany("App\Product");
}
This is the Category model where the Category has many product
Now in the product controller on listing function I want the list of product with category name
public function index()
{
$product = Product::with('categories')->get();
print_r($product->categories);die;
return view('product.index')->with("list",$product);
}
I want my Output should be
products
id name description category name
1 pro1 product 1 cat1
2 pro2 product 2 cat2
I found this error "Property [categories] does not exist on this collection instance."
When you run:
$product = Product::with('categories')->get();
you are not getting single products but all products so it should be rather renamed to:
$products = Product::with('categories')->get();
Further, looking at your database structure, each product belongs to single category so in Product model you should rename
public function categories()
{
return $this->belongsTo("App\Category");
}
to
public function category()
{
return $this->belongsTo("App\Category");
}
If you do this change, you should then again change
$products = Product::with('categories')->get();
to
$products = Product::with('category')->get();
Going back to your controller assuming all your products have set category, you can display it like this:
foreach ($products as $product)
{
echo $product->id.' '.$product->name.' '.$product->description.' '.$product->category->name;
}
You can obviously do the same later in Blade view like so:
#foreach ($list as $product)
{{ $product->id }} {{$product->name}} {{ $product->description }} {{ $product->category->name }}
#endforeach
I have changed in ProductController which is my product controllers function
public function index()
{
$products = Product::with('category')->get();
return view('product.index')->with("list",$products);
}
Also changed in Product Model
public function category() {
return $this->belongsTo("App\Category");
}
After these changes I got my expected result.
Thanks for taking the time to help.
I am building a blog in which I can associate categories. I'm saving the associated cats in the blog table by id.
Eg: category_blog_id = 1, 3, 9
I want to retrieve the categories by there title so thought the best approach was to write an accessor on the blog model.
Could someone point me in the right direction with this?
Should I add use CategoryBlog to the model and then explode the category_blog_id and run a foreach ver it?
That is what I have been trying, but it isn't working quite right yet and I wondered if there is a better, more Laravel-y way to do this?
Many thanks.
Actually, the relation between Post and Category could be many-to-many because a Category can has multiple posts under it and also a Post could be in more than one Category. So, if this is the case then you should create three tables like:
Table - posts:
id | post_title | post_slug | post_content | Others...
Table - categories:
id | category_title | category_slug | Others...
Table - category_post (Pivot table/ maintains relation between posts and categories):
id | category_id | post_id
Then you need two Models as Post and Category:
// Post model
class Post extends Eloquent {
public function categories() {
return $this->belongsToMany('Category');
}
}
// Category model
class Category extends Eloquent {
public function posts() {
return $this->belongsToMany('Post');
}
}
Create categories using something like this:
category::create(array(...)); // Input::all() (Mass Assignment)
Also you may create a Category using:
$category = new category;
$category->category_title = Input::get('category_title');
$category->category_slug = Input::get('category_slug');
// other fields (if have any)
$category->save();
Now create Post and attach categories:
$post = new Post; // Assume that, this is the first post so id would be 1
$post->title = 'My Post'; // Input::get('post_title');
$post->slug = 'mypost'; // Input::get('post_slug');
// Assign other values like post_content etc then
$post->save();
Once the Post is saved then:
// Attach two categories with this post using category id
$post->categories()->sync(array(1, 2)); // These (1, 2) are category ids
So, now you have a Post and this Post belongs to to categories, in other words, this post has been created under two categories by syncing the the post and categories, you are actually making a relation between the post and two categories and these relational data will be saved in category_post table so according to this example you category_post table will contain something like this:
id | category_id | post_id
----------------------------
1 | 1 | 1
2 | 2 | 1
Now you may query using Post model to get all the posts with categories like this:
$posts = Post::with('categories')->get();
Also find a single post by id with categories related to it using something like this:
$post = Post::with('categories')->find(1);
You may access the related categories using this:
$post->categories->get(0); // first category from the collection
$post->categories->get(1); // second category from the collection
If you pass the collection of Post models to your view like this;
$posts = Post::with('categories')->get();
return View::make('post.index')->with('posts', $posts);
Then in the view you may loop all posts and categories like this:
#foreach($posts as $post)
{{ $post->post_title }}
{{ $post->post_content }}
#foreach($post->categories as $category)
{{ $category->title }}
#endforeach
#endforeach
You may also use the Category model like:
// Get all categories with related posts
$categories = Category::with('posts')->get();
// Get a category using it's id with related posts
$category = Category::with('posts')->find(2); // Category id 2
This is the basic idea, read the manual (Eloquent ORM) for more.
Don't ever store delimited values in the database! Instead introduce a many-to-many (pivot) table blog_category in addition to blogs and categories tables. It will allow you to normally maintain and query your data using the means that relational database gives you (e.g. JOINs).
The schema for such table may look like something this:
CREATE TABLE blog_category
(
blog_id INT UNSIGNED NOT NULL,
category_id INT UNSIGNED NOT NULL,
PRIMARY KEY (blog_id, category_id),
FOREIGN KEY (blog_id) REFERENCES blogs (id),
FOREIGN KEY (category_id) REFERENCES categories (id)
);
A Laravel migration for such table may look like
class CreateBlogCategoryTable extends Migration {
public function up() {
Schema::create('blog_category', function(Blueprint $table)
{
$table->integer('blog_id')->unsigned();
$table->integer('category_id')->unsigned();
$table->foreign('blog_id')->references('id')->on('blogs');
$table->foreign('category_id')->references('id')->on('categories');
$table->primary(['blog_id', 'category_id']);
});
}
public function down() {
Schema::drop('blog_category');
}
}
Laravel Eloquent supports many-to-many relationships out of the box:
In Blog model
class Blog extends Eloquent {
public function categories() {
return $this->belongsToMany('Category');
}
}
and in Category model
class Category extends Eloquent {
public function blogs() {
return $this->belongsToMany('Blog');
}
}
Now you can access blogs through categories
$blogs = Category::find(1)->blogs();
or categories to which a specific blog belongs
$categories = Blog::find(1)->categories();