I want to display only 3 news in each category to display the last 3 news that were added.
Class category:
class category extends Model
{
use HasFactory;
public function articles(){
return $this->hasMany(Article::class)->limit(3)->orderBy('created_at', 'desc');
}
}
Class Article:
class Article extends Model
{
use HasFactory;
public function category(){
return $this->belongsTo(category::class);
}
}
$categories = category::with('articles')->limit(3)->get();
$articles = Article::orderBy('created_at', 'desc')->get();
return response()->view('news.index', compact('categories','articles'));
use whereHas
$categories = category::whereHas('articles', function($query){
return $query->orderBy('created_at', 'desc')->limit(3);
})->get();
return view('news.index', compact('categories'));
By using latest()
$categories = category::whereHas('articles', function($query){
return $query->latest()->take(3);
})->get();
return view('news.index', compact('categories'));
Related
I have Post, Tag and Category models. I know how to get posts by tag or posts by category. But I need to get posts by chosen tag and category simultaneously (at one time). Can somebody help? I use Laravel 8.
Post model
class Post extends Model
{
public function category()
{
return $this->belongsTo(Category::class);
}
public function tags()
{
return $this->belongsToMany(
Tag::class,
'post_tag',
'post_id',
'tag_id'
);
}
}
Tag model
class Tag extends Model
{
public function posts()
{
return $this->belongsToMany(
Post::class,
'post_tag',
'tag_id',
'post_id'
)->withTimestamps();
}
}
Category model
class Category extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
Post controller's methods
class PostController extends Controller
{
public function show($slug)
{
$post = Post::where('slug', $slug)->orderBy('date', 'desc')->firstOrFail();
return view('pages.post', compact('post'));
}
public function tag($slug)
{
$tag = Tag::where('slug', $slug)->firstOrFail();
$posts = $tag->posts()->orderBy('date', 'desc')->paginate(7);
return view('pages.postlist', ['posts' => $posts]);
}
public function category($slug)
{
$category = Category::where('slug', $slug)->firstOrFail();
$posts = $category->posts()->orderBy('date', 'desc')->paginate(7);
return view('pages.postlist', ['posts' => $posts]);
}
}
Routes
Route::get('/posts/{slug}', 'App\Http\Controllers\PostController#show')->name('post.show');
Route::get('/posts/tag/{slug}', 'App\Http\Controllers\PostController#tag')->name('ptag.show');
Route::get('/posts/category/{slug}', 'App\Http\Controllers\PostController#category')->name('pcategory.show');
You might want to use whereHas:
$categoryId = 1;
$tagId = 2;
Post::whereHas('category', function ($query) use ($categoryId) {
$query->whereKey($categoryId);
})->whereHas('tags', function ($query) use ($tagId) {
$query->whereKey($tagId);
})->get();
In my Laravel 6.x project I have Product model, Warehouse and WarehouseProduct models.
In the Product I store the base information of my products. In the WarehouseProduct I store the stock amount informations about products in warehouse. Of course I have many warehouses with many products.
My Product looks like this:
class Product extends Model
{
protected $fillable = [
'name',
'item_number',
// ...
];
}
The Warehouse looks like this:
class Warehouse extends Model
{
protected $fillable = [
'name',
'address',
// ...
];
public function products() {
return $this->hasMany(WarehouseProduct::class);
}
public function missingProduct() {
// here I need to return a Product collection which are not in this Warehouse or the
// stored amount is 0
}
}
Finally the WarehouseProduct looks like this:
class WarehouseProduct extends Model
{
protected $fillable = [
'product_id',
'warehouse_id',
'amount',
// ...
];
public function product() {
return $this->belongsTo(Product::class, 'product_id');
}
public function warehouse() {
return $this->belongsTo(Warehouse::class, 'warehouse_id');
}
How can I get a Product collection which are not stored in a Warehouse or the amount is 0?
Something like this should work:
use App\Product;
public function missingProduct() {
$excludedProducts = $this->products()->where('amount', '>', 0)->pluck('id');
return Product::whereNotIn('id', $excludedProducts)->get();
}
Based on #KarolSobaĆski's solution, when you add a warehouse_products relation to your product model:
use App\Product;
use Illuminate\Database\Eloquent\Builder;
public function missingProduct() {
return Product::whereDoesntHave('warehouse_products', function (Builder $query) {
$query->where('warehouse_id', $this->id);
})->orWhereHas('warehouse_products', function (Builder $query) {
$query->where('warehouse_id', $this->id);
$query->where('amount', 0);
})->get();
}
The shortest answer might be similar to this:
Product::doesntHave('warehouse_products')
->orWhereHas('warehouse_products', function (Builder $query) {
$query->where('amount', '=', 0)
})->get();
Although I am not sure if the above works.
But the following longer query certainly resolves the issue:
Product::where(function ($query) {
$query->doesntHave('warehouse_products');
})->orWhere(function ($query) {
$query->whereHas('warehouse_products', function (Builder $query) {
$query->where('amount', '=', 0);
});
})->get();
This works fine but what I want to know is if there is a better way to do a search for tags in Laravel. Thanks.
Tag model:
class Tag extends Model
{
public function noticias()
{
return $this->morphedByMany('App\Models\Noticia', 'taggable');
}
// ...
}
Noticia model:
class Noticia extends Model
{
public function tags()
{
return $this->morphToMany('App\Models\Tag', 'taggable');
}
// ...
}
SearchController
public function tag($id){
$noticias= Noticia::all();
$data['noticias'] = [];
foreach($noticias as $value){
foreach($value->tags as $tag){
if($tag->id == $id){
$data['noticias'][] = $value;
}
}
}
return view('web.buscar.index');
}
use whereHas()
$noticias= Noticia::with('tags')->whereHas('tags', function($q) use ($id){
$q->where('id',$id);
})->get();
To get only ids use pluck()
$noticias= Noticia::whereHas('tags', function($q) use ($id){
$q->where('id',$id);
})->pluck('id');
Try this,
public function tag($id){
$noticicas = Noticia::has(['tags'=> function($query) use($id){
return $query->where('id',$id);
}])->get();
dd($noticicas);
//you can also, get the tag with the id you send, and then get all the `Noticias` for it
$tag = Tag::find($id);
$noticias = $tag->noticias->with(["tags"]); // the with is in case you want to show all the tags from the news
}
Hi try to get my products list in subcategory page but i'm getting this error
Call to undefined method App\Product::whereHas()
here is my function
// Subategory page included posts
public function productsubcategory($slug)
{
$products = Product::whereHas('subcategory.category', function($q) use($slug){
$q->where('slug',$slug);
})->paginate(6);
return view('frontend.subcategories', compact('products'));
}
this is my route:
Route::get('/category/{slug}/subcategory/{subslug}', ['as' => 'showbysub', 'uses' => 'IndexController#productsubcategory']);
my product model:
public function categories(){
return $this->belongsTo(Category::class);
}
public function subcategories(){
return $this->belongsTo(Subcategory::class);
}
category model:
public function products(){
return $this->hasMany(Product::class);
}
public function subcategories(){
return $this->hasMany(Subcategory::class);
}
subcategory model:
public function category(){
return $this->belongsTo(Category::class, 'category_id');
}
public function products(){
return $this->hasMany(Product::class);
}
any idea?
UPDATE:
I changed my function to:
public function productsubcategory($slug)
{
$subcategories = Subcategory::where('slug','=',$slug)->with('products')->paginate(6);
return view('frontend.subcategories', compact('subcategories'));
}
and now my page is loading but will not show any item (product).
UPDATE 2
I changed my function to this:
public function productsubcategory($slug)
{
$products = Product::with('subcategories')
->orderBy('id', 'desc')
->get();
return view('frontend.subcategories', compact('products'));
}
Now I can get products but the problem is all products will show even
if they're included other categories.
How to solve that?
I don't understand what do you mean in this lines
$products = Product::whereHas('subcategory.category', function($q) use($slug){
$q->where('slug',$slug);
})->paginate(6);
Refer to https://laravel.com/docs/5.4/eloquent-relationships. If you are trying to querying relationship, you can do like this:
$products = Product::whereHas('subcategories', function($q) use($slug){
$q->where('slug',$slug);
})->paginate(6);
or
$products = Product::whereHas('categories', function($q) use($slug){
$q->where('slug',$slug);
})->paginate(6);
The relationship name must the same with relationship method in your Product model
SOLVED
public function productsubcategory($slug, $subslug)
{
$products = Product::whereHas('subcategory', function($q) use($subslug){
$q->where('slug',$subslug);
})->get();
return view('frontend.subcategories', compact('products'));
}
and product model from subcategories change to subcategory
This is my first laravel Application, and my first database based application so please be patient with me !!
I will try to be specific!!
Categories Table:
Id
Name
Timestamps
Posts table:
Id
title
body
slug
Category_id
timestamps
Lets say i have 4 catergories.
Laptops, computers,phones,tablets
I want when i go to /computers to be able to get all the posts that are specific to that category.
Posts Model
Category Model
Category Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
use App\Category;
class CatController extends Controller
{
public function getCategory($Category_id)
{
$posts = Post::where('Category_id',$Category_id);
return view('blog.index',['posts' => $posts]);
}
Route:
Route::get('computer/{Category_id}','CatController#getCategory');
I am really confused at the moment !!
Thanks everyone in advance!!
Define your Model
class Category extends Model
{
/**
* Get the posts.
*/
public function posts()
{
return $this->hasMany('App\Post', 'Category_id');
}
}
class Post extends Model
{
/**
* Get the category.
*/
public function category()
{
return $this->belongsTo('App\Category', 'Category_id');
}
}
Define your Controller
class CatController extends Controller
{
public function getCategory($Category_id)
{
$category = Category::find($Category_id);
if($category !== null){
$posts = $category->posts;
return view('blog.index',['posts' => $posts]);
}
}
I hope this will help you.
Route:
Route::get('categories/{category_id}/computers','CatController#show');
Controller:
public function show($category_id)
{
$category = Category::findOrFail($category_id);
if($category){
$posts = Post::where('Category_id',$category_id)->get();
return view('category.index', compact('posts'));
}
return view('errors.404');
}
Simply add this to your controller
public function category($id){
$data['posts'] = Post::where('status', 1)->where('category_id', $id)->orderBy('id', 'DESC')->get();
return view('frontEnd.home', $data);
}