i have some issues that happen with my code for displaying posts by category..
Relation is one to many, post to category.. I can route to choosen category, but posts did not show..
Here's my Post Model:
public function category()
{
return $this->belongsTo(CategoriesPost::class);
}
Category Model:
public function posts()
{
return $this->hasMany(Post::class, 'category_id');
}
And here's my PostController
$posts = Post::where('article_status', 'published')->whereHas('category', function ($query) use ($slug) {
return $query->where('category_slug', $slug);
});
$category = CategoriesPost::where('category_slug', $slug)->first();
return view('pages.article', [
'posts' => $posts,
'category' => $category,
]);
I'm so sure my code was right, but why it didn't shows the posts, did anyone notice where's the problem of my code?
Rather than querying for the related Posts separately, why not access them via the relationship you have defined in your Category model? It will improve performance by reducing the number of calls to your database for a start.
So something like:
$category = CategoriesPost::with(['posts'])->where('category_slug', $slug)->first();
Then you can just access your posts relationship on the $category property in your view:
$category->posts;
Related
I have a many to many between Article and Category model and a pivot containing category_id and article_id records. At the click on the category link I would have a page that shows me all articles related to the category clicked but i can't create the right function in the controller.
public function showcategory($id){
$articles=Article::whereHas('categories',function($query){
$query->whereIn('category_id', $id);
})->get();
return view('categorydetail',compact('articles);
}
Your code seems not fine. Eloquent whereIn is expecting an array as second parameter. Use where instead.
$articles=Article::whereHas('categories',function($query){
$query->where('category_id', $id);
})->get();
Ideally, this is not the best practice. You'd better try the flow below:
//Category.php
public function articles() {
return $this->belongsTo(Article::class);
}
//Controller
$category = Category::with('articles')->find($id);
if (empty($category)) {
//show 404 error or redirection
}
$articles = $category->articles()->get();
Your code is correct, you just need to pass the id variable
The variable is passed using the code by adding the following code use($id)
You should use where instead of whereIn
public function showcategory($id){
$articles=Article::whereHas('categories',function($query) use($id){
$query->where('category_id', $id);
})->get();
return view('categorydetail',compact('articles));
}
There is also another way
public function showcategory($id){
$category= Category::find($id);
empty($category) ? abort(404) : '';
$articles = $category->articles()->paginate(10);
return view('categorydetail',compact('articles));
}
I have looked through the forum, but the solutions I have seen so far, aren't aligning with the issues I'm getting, so, I was hoping someone more informed would help out.
So I have a Category modem and A post model and there relationship is as follows;
on post model:
public function postcategory(){
return $this->belongsTo(PostCategory::class);
}
on category model:
public function posts(){
return $this->hasMany(Post::class)->where('approved', 'true');
}
and I am using slugs to retrieve all the posts that belongs to a certain category slug, using this function:
public function cats($category){
$posts = PostCategory::where('category_slug', $category)->first()->posts;
$category = PostCategory::where('category_slug', $category)->first();
return view('posts', compact('posts', 'category'));
}
Now, I am trying to get the name of the category with the category id stored in the posts table. for example, if I have a category id of 1 and on the category table, if the id number 1 is PHP, how do I return the name PHP instead of the id 1?
Secondly, if I wanted to paginate the view where posts is being compacted to, how do I do that? I switched the code in the controller to this:
$posts = PostCategory::with('posts')->where('category_slug', $category)->paginate(15);
when I dd that line of code, it returns some values (with relations), but when I pass that to the view, I get errors.
Hopefully, someone see this and help me out. :D
on Category Model :
public function posts()
{
return $this->hasMany(Post::class);
}
On Controller :
public function cats($slug)
{
$category = PostCategory::whereSlug($slug)->firstorFail();
$posts= $category->posts()->where('approved', 'true')->paginate(15);
return view('category.show', compact('posts', 'category'));
}
On View :
#foreach($posts as $post)
$post->title
....
#endforeach
{{ $posts->links() }}
I've spent two days trying to solve this but I can't figure how.
I have five tables
Product
Category
Category_Product
Order
Order_Product
From the view,clicking on a category button I have to fetch all his ordered products with the relative category.
I have the current models:
Product Model
class Product extends Model
{
public function categories() {
return $this->belongsToMany('App\Category');
}
public function orders() {
return $this->belongsTo('App\Order');
}
}
Category Model
public function products() {
return $this->belongsToMany('App\Product');
}
Order Model
public function products() {
return $this->belongsToMany('App\Product');
}
Now the problem is that I can't figure how to fetch the data from the current tables.When I press a button I'm able to fetch the category from the Product Table,but I want to fetch from the Ordered_Products. I really can't figure how.
With this I'm able to fetch all the categories from Product
if (request()->category) {
$products = Product::with('categories')->whereHas('categories', function ($query) {
$query->where('slug', request()->category);
})->get();
}
With this instead,I'm able to fetch the ordered products.
$products = DB::table('order_product')
->join('products', 'order_product.product_id','=', 'products.id')
->where('order_product.user_id','=',$user_id)
->get();
For the latter, there's a better way to do it, that's for sure. I'm sorry if it's a dumb question but I'm rather new with this framework. I am using Laravel 7.2.
Basically Eloquent Model doesn't encourage joining tables to retrieve data. It should be joined only for filtering results (So you need to drop field of other table using ->select('original_table.*'))
In this case, you should simply retrieve categories at first. Then retrieve related data using relation property accessing.
e.g.
$categories = Category::query()
->with('products')
->where('slug', request('category'))
->get();
$products = $categories->flatMap->products;
$pivots = $products->map->pivot;
Solved using whereHas two times:
$products = Product::with('categories')->whereHas('categories',function($query){
$query->where('slug',request()->category);
})->whereHas('orders',function($query){
$query->where('orders.user_id',Auth::id());
})->get();
I have two tables
product: id|category ...
category: id|name ...
product.category is a foreign key linked to category.id . I am building a basic CRUD and I would like to display all Products in the the product table as well as the name of the category they belong to rather than their category ID. TO do this, while searching the laravel documentation I came across the query builder and I achieved my goal.
public function index()
{
$products = \DB::table('products')
->join('categories', 'products.category', '=', 'categories.id')
->select('*')
->get();
return view('product' ,compact('products'));
}
Under my models for product and category I have created the appropriate relationships.
product.php :
public function category()
{
return $this->belongsTo('App\Category');
}
category.php :
public function products()
{
return $this->hasMany('App\Product');
}
I keep hearing about the power of Eloquent and was wondering how I could achieve a similar result with eloquent and if eloquent is designed for such operations or if the query builder is the right way to go.
Every tutorial online seems to only use the post and comments scenario of getting all comments belonging to a post.
You can use this code
public function index()
{
$products = Product::with('category')->get();
return view('product' ,compact('products'));
}
In blade
#foreach($products as $product)
{{$product->name}}
{{$product->category->name ?? ''}}
//or
#if ($product->category)
$product->category->name
#endif
#endforeach
Also if in project table foreign key is not equal category_id. In your case
public function category()
{
return $this->belongsTo('App\Category', 'category');
}
I am working on a laravel based project comprising of Authors, Posts and Comments as models.
The relationship between the models is as follows:
Author -> hasMany Post
Post -> hasMany Comment.
The problem is as follows:
Authors made multiple posts, and all of them have multiple comments. I want to get the count of the Authors with comments from internal members only on their latest post.
My Models are shown below-
Author.php
public function post() {
return $this->hasMany('App\Post');
}
public function latestPost() {
return $this->hasOne('App\Post', 'latest_post_id', 'id')-
>orderBy('created_at', 'desc');
}
Post.php
public function comment() {
return $this->hasMany('App\Comment', 'post_id', 'id');
}
The query I am using to get the data are as follow:
$author_count = Author::whereHas('latestPost.comment', function ($query) {
$query->createdByInternal();
})->count();
When I execute this query, it considers all the Post models instead of only the latest Post and gives the authors who have a comment by an Internal member on any of their post.
However, on eager loading the latestPost query using "with" function, I get only the comments on the latest post.
$author = Author::with('latestPost.comment')->get();
Thanks in advance.
If you want to count authors who have posts with no created_by_internal
= null comments, use whereDoesntHave():
Author::whereDoesntHave('latestPost.comment', function ($query) {
$query->notCreatedByInternal();
})
->count();
In the relationship definition put foreign key before the id:
public function latestPost()
{
return $this->hasOne('App\Post', 'latest_post_id', 'id')->latest();
}
Also, change to scope to:
public scopeNotCreatedByInternal($query)
{
return $query->whereNull('created_by_internal');
}