how can i join multiple tables in eloquent using relationships? - php

How should i join these 4 tables users, pages, category, products using relationships intead in controller.I also prefer calling these functions from corresponding models using respective function names but not database column names in view.
These are my models:
User model:
class User extends Authenticatable{
use HasFactory, Notifiable;
protected $fillable = ['id','name' ];
protected $hidden = [ 'password', 'remember_token', ];
protected $casts = ['email_verified_at' => 'datetime', ];
public function getuserName(){
if($this->name){ return "$this->name"; }
return null;
}
public function page(){
return $this->hasMany('App\Models\Pages', 'user_id');
}
public function product(){
return $this->hasMany('App\Models\Products', 'user_id');
}
}
Products model:
class products extends Model {
use HasFactory;
protected $table = 'products';
protected $fillable = [ 'id', 'user_id', 'parent_page_id', 'pcategory_id', 'prodname', ];
/**get id(PK)****/
public function fetchid(){
if($this->id){ return $this->id; }
return null;
}
/**get pageid (FK)****/
public function fetchpageid(){
if($this->parent_page_id){ return $this->parent_page_id; }
return null;
}
/**get categoryid (FK)****/
public function fetchcategoryid(){
if($this->pcategory_id){ return $this->pcategory_id; }
return null;
}
/**get product owner****/
public function fetchuser_id(){
if($this->user_id){ return $this->user_id; }
return null;
}
/**get product name****/
public function fetchprodname(){
if($this->prodname){ return $this->prodname; }
return null;
}
/**pick session userid from User model****/
public function user(){
return $this->belongsTo('App\Models\User', 'user_id');
}
}
Post model:
class pages extends Model {
use HasFactory;
protected $table = 'pages';
protected $fillable = [ 'page_id', 'user_id', 'pagename', ];
/**get page id(PK)****/
public function fetchpage_id(){
if($this->page_id){ return $this->page_id; }
return null;
}
/**get page owner****/
public function fetchuser_id(){
if($this->user_id){ return $this->user_id; }
return null;
}
/**get page name****/
public function fetchpagename(){
if($this->pagename){ return $this->pagename; }
return null;
}
/**pick session userid from User model****/
public function user(){
return $this->belongsTo('App\Models\User', 'user_id');
}
}
Category model:
class category extends Model {
use HasFactory;
protected $table = 'category';
protected $fillable = [ 'category_id', 'name', ];
/**get category id(PK)****/
public function fetchcategory_id(){
if($this->category_id){ return $this->category_id; }
return null;
}
/**get category name****/
public function fetchcname(){
if($this->name){ return $this->name; }
return null;
}
}
How should i join these 4 tables users, pages, category, products using relationships intead
$carousel = Products::where(function($querycarousel ) {
return $querycarousel
->leftJoin('users', 'products.user_id', 'users.id')
->leftJoin('pages', 'products.parent_page_id', 'pages.page_id')
->leftJoin('category', 'products.pcategory_id', 'category.category_id')
->where('products.verification_status', 'Verified')
->where('category.name', 'New');
})->inRandomOrder()
->limit(50)
->get();
return view('pages.home')->with('carousel ', $carousel );
View
I also prefer calling these functions from corresponding models using respective function names but not database column names
#foreach ($carousel->chunk(5) as $key => $batchresults)
#foreach ($batchresults as $key => $feed)
<div>
<p>{{ $feed->fetchprodname() }}</p>
<p>{{ $feed->fetchcname() }}</p>
<p>{{ $feed->fetchpagename() }}</p>
<p>{{ $feed->getuserName() }}</p>
</div>
#endforeach
#endforeach

Related

Laravel Eloquent get all Posts stored in categories with Roles

I have four tables in a database named: Category, User, Role and then Post. In the Category table I have a column category_id which by this column i can have multiple child in category.
Every user belongsToMany roles and categories and each category belongsToMany posts, i must get all posts by role which logged into our application
As you can see in below screen shot manager 1 and manager 2 belongsToMany programings, dart, flutter and php.
you can suppose manager 1 user id is 1 and manager 2 is 2 and both of them are manager role
my question is how can i get all posts which logged user belongsToMany categories by role
logged user is manager 1 and i want to get all posts which saved into categories from parent which that's PROGRAMINGS
for example:
$categories = Category::whereNull('category_id')->whereHas('users.roles', function($q){
return $q->whereLabel('is-manager');
})->with(['posts' => function ($query) {
$query->with('language');
}])->get();
dd($categories->pluck('posts'));
NOTE:
with #Med.ZAIRI answer which posted on this thread every user in MANAGER 2 which is't synced into MANAGER 1, can see all of MANAGER 1 posts
In the Model Category add a relationship, like:
/**
* this will get the parent category
*/
public function parentCategory()
{
return $this->belongsTo( Category::class, 'category_id', 'id' );
}
Then, try to get Posts with their categories and their parent
Categories, and the users with their Roles, like:
$posts = Post::with( ['category.parentCategory', 'user.roles'])->get()
my used models in this senario:
class Category extends Model
{
use SoftDeletes;
protected $guarded = ['id'];
protected $hidden = ['id', 'category_id'];
public function parentCategory()
{
return $this->belongsTo( Category::class, 'category_id', 'id' );
}
public function categories()
{
return $this->hasMany(Category::class);
}
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function posts()
{
return $this->belongsToMany(Post::class);
}
public function users()
{
return $this->belongsToMany(User::class);
}
public function childrenCategories()
{
return $this->hasMany(Category::class)->with('categories');
}
}
class Role extends Model
{
protected $guarded = ['id'];
public function users()
{
return $this->belongsToMany(User::class);
}
public function permission()
{
return $this->belongsToMany(Permission::class);
}
public function hasPermission($permission)
{
return !!$permission->intersect($this->roles->permission)->count();
}
}
class User extends Authenticatable
{
use Notifiable, SoftDeletes, UsersOnlineTrait;
protected $guarded = [
'id',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
'avatar_path' => 'array',
'experiences' => 'array',
];
public function group()
{
return $this->belongsToMany(UserGroup::class, 'user_user_group');
}
public function child()
{
return $this->hasMany(User::class)->with('child');
}
public function parent()
{
return $this->belongsTo(User::class, 'user_id');
}
public function properties()
{
return $this->hasOne(UsersProperty::class);
}
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function hasRole($role)
{
return $this->roles->contains('id', $role);
/*if (is_string($role)) {
} else {
return !!$role->intersect($this->roles)->count();
}*/
}
public function hasRoleByName($role)
{
if ($role == null) return false;
if (is_string($role)) {
return $this->roles->contains('name', $role) || $this->roles->contains('label', $role);
} else {
return !!$role->intersect($this->roles)->count();
}
}
public function categories()
{
return $this->belongsToMany(Category::class);
}
}
In the Model Category add a relationship, like:
/**
* this will get the parent category
*/
public function parentCategory()
{
return $this->belongsTo( Category::class, 'category_id', 'id' );
}
Then, try to get Posts with their categories and their parent Categories, and the users with their Roles, like:
$posts = Post::with( ['category.parentCategory', 'user.roles'])->get()
Trait with methods to get all available posts for the logged in user
based on the role
class User extends Model
{
use HasFactory, Notifiable, HasPosts;
}
<?php
namespace App\Concerns;
use App\Models\Category;
use Illuminate\Support\Str;
use Illuminate\Support\Collection;
trait HasPosts
{
/**
* Get all available posts for the currently logged in user
*
* #return void
*/
public function posts()
{
$method = 'postsFor' . Str::studly(str_replace('is-', '', $this->roles->first()->label));
return $this->{$method}()->collapse();
}
/**
* Get all posts associated with all categories including
* their subcategories for the logged in Portal Manager
*/
public function postsForPortalManager(): Collection
{
return Category::with([
'subcategories.posts.language',
'posts.language'
])
->get()
->pluck('posts');
}
/**
* Get all posts for the logged in Manager which belong to
* one of the categories associated with the Manager
*/
public function postsForManager(): Collection
{
return $this->categories()
->with('posts.language')
->get()
->pluck('posts')
->filter(function ($collection) {
return !!$collection->count();
});
}
/**
* Get only the posts which belong to the categories for the Editor
* and which are authored by the logged in Editor
*/
public function postsForEditor(): Collection
{
return $this->categories()
->with([
'posts' => function ($query) {
$query->where('user_id', $this->id)->with('language');
},
'posts.language'
])
->get()
->pluck('posts')
->filter(function ($collection) {
return !!$collection->count();
});
}
/**
* Get only the posts which belong to the categories for the Writer
* and which are authored by the logged in Writer
*/
public function postsForWriter(): Collection
{
return $this->categories()
->with([
'posts' => function ($query) {
$query->where('user_id', $this->id)->with('language');
},
'posts.language'
])
->get()
->pluck('posts')
->filter(function ($collection) {
return !!$collection->count();
});
}
}
Then for any authenticated user we can fetch available posts with
$user->posts()
It works with the seed data you have provided.
ella is not able to see the post on Flutter and scarlett is not able to see the post on laravel
Only assumption here is that have taken the first role of the authenticated user to lookup the method used.
Add this to your roles model:
public function categories()
{
return $this->hasMany(Category::class);
}
After that you can reach posts from the user, like:
$authorizedUser->roles()->with('categories.posts')->get();
You can flatten the result to access posts directly as well
If your relationships are all many-to-many as below:
roles >-< users >-< categories >-< posts
and are all defined properly in the models, e.g.
// Role.php
public function users()
{
return $this->belongsToMany(User::class);
}
// User.php
public function categories()
{
return $this->belongsToMany(Category::class);
}
// Category.php
public function posts()
{
return $this->belongsToMany(Post::class);
}
then I'm pretty sure you should be able to do
$role = Role::find(1);
// get all posts from all categories from all users with $role
$posts = $role->users()->categories()->posts;

Laravel categories relationship returns null

I'm trying to make relationship table for products and categories.
This is my Products Model
protected $table = 'products';
protected $fillable = ['sku', 'slug', 'type'];
public function category()
{
return $this->belongsTo('Modules\Product\Entities\Categories', 'categories_products', 'category_id', 'id');
}
And this is my Categories model:
protected $table = 'categories';
protected $fillable = ['parent_id', 'name'];
public function parent()
{
return $this->hasOne(self);
}
public function products()
{
return $this->hasMany('Modules\Product\Entities\Products', 'categories_products', 'product_id', 'id');
}
Every time when I try to get Products with categories like so:
public function getProducts()
{
return Products::with('category')->get();
}
It's returning that category is null. My relation ship table is called categories_products and it have 2 integers product_id and category_id.
You should have a belongsTomany relationship in your model.
Product Model
protected $table = 'products';
protected $fillable = ['sku', 'slug', 'type'];
public function categories()
{
return $this->belongsToMany('Modules\Product\Entities\Categories', 'categories_products', 'product_id', 'category_id');
}
Category model
protected $table = 'categories';
protected $fillable = ['parent_id', 'name'];
public function parent()
{
return $this->belongsTo('Modules\Product\Entities\Categories','parent_id','id');
}
public function products()
{
return $this->belongsToMany('Modules\Product\Entities\Product', 'categories_products', 'category_id', 'product_id');
}

How to retrieve and display relationship data in Laravel?

I have three tables in the database. orders, products, and order_product table. this is how they look like in my phpmyAdmin https://imgur.com/a/Ud9e2Hh
I would like sellers to see orders placed by buyers in their view (dashboard). Also, buyers to be able to see their orders in their view.
Here are my relationships in models
User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'Seller'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
//public function isSeller() {
// return $this->seller;
//}
public function products()
{
return $this->hasMany(Products_model::class);
}
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function orders()
{
return $this->hasManyThrough(Order::class, Products_model::class, 'buyer_id', 'seller_id', 'product_id');
}
public function orderFromBuyers()
{
return $this->hasManyThrough(OrderProduct::class, Products_model::class, 'buyer_id', 'product_id');
}
public function orderFromSellers()
{
return $this->hasManyThrough(OrderProduct::class, Products_model::class, 'seller_id', 'product_id');
}
}
OrderProduct.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class OrderProduct extends Model
{
protected $table = 'order_product';
protected $fillable = ['order_id', 'buyer_id', 'seller_id','product_id', 'quantity'];
public function products()
{
return $this->belongsTo('App\Products_model');
}
public function buyer()
{
return $this->belongsTo(User::class, 'id', 'buyer_id');
}
public function seller()
{
return $this->belongsTo(User::class, 'id', 'seller_id');
}
public function order()
{
return $this->belongsTo(Order::class);
}
}
Order.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
//protected $table = 'orders';
protected $fillable = [
'shipping_email', 'shipping_name', 'shipping_city', 'shipping_phone', 'billing_subtotal', 'billing_total',
];
public function user()
{
return $this->belongsTo('App\User');
}
public function products()
{
return $this->belongsToMany('App\Products_model')->withPivot('quantity');
}
public function orders()
{
return $this->hasMany('App\OrderProduct', 'order_id');
}
}
Seller Function
// Seller Orders
public function viewOrders(User $user)
{
// $products = Products_model::where('seller_id', '=', $user->id)->get();
// all sells
$sells = $user->orderFromSellers();
dd($sells);
return view('orders')->with(compact('sells'));
}
Buyer Function
//Buyer Orders
public function myOrders()
{
$cart = session();
$orders = Auth::user()->orders;
$orders->transform(function($order, $key) {
dd($orders);
$order->cart = unserialize($order->cart);
return $order;
});
return view('myOrders', ['orders' => $orders]);
}
Right now it shows nothing. Any help on how to solve this will be appreciated.
Products_model
protected $table='products';
protected $primaryKey='id';
protected $fillable=['seller_id','pro_name','pro_price','pro_info','image','stock','category_id '];
Try by changing two function.
public function orderFromBuyers()
{
return $this->hasManyThrough(Products_model::class, OrderProduct::class, 'buyer_id', 'product_id');
}
public function orderFromSellers()
{
return $this->hasManyThrough(Products_model::class, OrderProduct::class, 'seller_id', 'product_id');
}
Or the two will be more better. Add these two functions to User model.
public function allOrderFromBuyers()
{
return $this->hasMany(OrderProduct::class, 'buyer_id');
}
public function allOrderFromSellers()
{
return $this->hasMany(OrderProduct::class, 'seller_id');
}
Then change this to,
// Seller Orders
public function viewOrders(User $user)
{
// all sells
$sells = $user->allOrderFromSellers();
dd($sells);
return view('orders')->with(compact('sells'));
}

Problems calling relationships in Laravel

I'm getting problems calling relationships in laravel, I have 4 tables: users, tickets, stores, statuses. and I have a #OneToMany relationship in Users to Tickets (1 user have many tickets). the other relationships are #OneToOne (1 ticket have 1 store and status).
Now, I have 6 tickets in my table and 4 users, I can print the relationship to the 4 first tickets, but when I want to call the ticket 5 or 6, the relationship dissapears.
The same thing with store and status, I can print the relationship while the id of the ticket is not greater than the number of items I have in my table.
these are my models:
User Model:
class User extends Authenticatable
{
use Notifiable, HasRoles;
protected $fillable = [
'id','name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function tickets()
{
return $this->hasMany(Ticket::class, 'usuario_id');
}
}
Ticket Model:
class Ticket extends Model
{
protected $fillable = [
'comentarios', 'falla', 'modelo', 'no_serie', 'monto',
'usuario_id', 'status_id', 'store_id'
];
public function user()
{
return $this->belongsTo(User::class, 'id');
}
public function store()
{
return $this->hasOne(Store::class, 'id');
}
public function status()
{
return $this->hasOne(Status::class, 'id');
}
}
Store Model:
class Store extends Model
{
protected $table = "stores";
protected $primaryKey = 'id';
public $timestamps = false;
protected $fillable = [
'sucursal', 'dirección'
];
public function ticket()
{
return $this->belongsTo(Ticket::class, 'store_id');
}
}
Status Model:
class Status extends Model
{
public $timestamps = false;
protected $fillable = [
'status'
];
public function ticket()
{
return $this->belongsTo(Ticket::class, 'status_id');
}
}
Controller:
$tickets = Ticket::all();
return view('Admin.index', compact('tickets'));
View
#foreach($tickets as $ticket)
<li>{{ $ticket->user }}</li>
#endforeach
result:
Result of the foreach
In the view, I'm calling all the tickets ($tickets), and for each ticket, I print the relationship (user function). But in the result, you can see that just print first 4 relationships, (the number of my users), if I add 1 user, the relationship in the 5th ticket appears.
The Same problem with the other tables (store and status).
Replace user() relationship in Ticket moedel to:
public function user()
{
return $this->belongsTo(User::class, 'usuario_id', 'id');
}
in Ticket model you must change function to
public function user()
{
return $this->belongsTo(User::class, 'usuario_id', 'id');
}
or just public function user()
{
return $this->belongsTo(User::class);
}

Laravel comments and user relationship returns null

I'm trying to implement commenting system on my website but i'm having hard time with the relationships. for some reason when i try to access the user relation from the comment class it returns null.. my code:
Post.php
class Post extends Model
{
public $timestamps = false;
public $primaryKey = 'post_id';
protected $fillable = ['title','created_at','username','image'];
public function user()
{
return $this->belongsTo(User::class,'username');
}
public function votes()
{
//Quick note: Id refers to the post id.
return $this->hasMany(PostVotes::class,'post_id');
}
public function comments()
{
return $this->hasMany(Comment::class,'post_id');
}
}
User.php
class User extends Model implements Authenticatable
{
use AuthenticableTrait;
protected $primaryKey = 'username';
public $incrementing = false;
public $timestamps = false;
protected $fillable = ['username','email','password','created_at','avatar','about'];
// Gets avatar to display on navbar.
public function posts()
{
return $this->hasMany(Post::class,'username');
}
public function comments()
{
return $this->hasMany(Comment::class,'username');
}
public static function getAvatar()
{
return self::Where('username', '=', Session::get('username'))->value('avatar');
}
}
Comment.php
class Comment extends Model
{
public $timestamps = false;
public $primaryKey = 'post_id';
protected $fillable = ['comment','created_at','post_id','username'];
public function user()
{
$this->belongsTo(User::class,'username') ;
}
public function post()
{
$this->belongsTo(Post::class,'post_id');
}
}
public function view($post_id)
{
$post = Post::with('comments')->findOrFail($post_id);
return view('posts.view',compact('post'));
}
#foreach($post->comments as $comment)
// null
{{dd($comment->user())}}
#endforeach
Use missed the return keyword
public function user()
{
return $this->belongsTo(User::class,'username') ;
}
public function post()
{
return $this->belongsTo(Post::class,'post_id');
}
public function displaycomment($id) {
$data['comment'] = comment::select('comments.id', 'comments.description', 'users.name', 'comments.created_at', 'comments.post_id')->where('post_id',$id)->leftjoin('users', 'users.id', '=', 'comments.user_id')->get();
// dd($data);
return view('displayblog', compact('data'));
}

Categories