I can not select users that have departments in laravel - php

$users = User::with('departments')
->whereHas('departments', function ($q) use ($departments) {
return $q->whereIn('department_id', $departments);
})->whereNotNull('users.email')
->get();
public function users(){return $this->morphedByMany(User::class, 'departmentable');}
in department model
and
public function departments(){return $this->morphToMany(Department::class, 'departmentable');
}
in user model

in your whereIn statement you use department_id column in departments table, are you sure of this, isn't just 'id' ('departments.id')?
$users = User::with('departments')
->whereHas('departments', function ($q) use ($departments) {
return $q->whereIn('departments.id', $departments);
})->whereNotNull('users.email')
->get();

Related

Laravel Relationship with condtion on foreign key (toggle foreign key on relation)

For a small chat purpose, I am using below relationship
Model
class Chat extends Model
{
protected $table = 'chats';
protected $primaryKey = 'chat_id';
protected $filllable = [
'chat_id',
'sender_id',
'reciever_id',
'content',
'sender_type',
'reciever_type',
'view_status'
];
class Admin extends Authenticatable
{
public function chats()
{
return $this->hasMany(Chat::class, 'sender_id', 'admin_id');
}
}
but the issue is both user's are in the same table some times it is sender_id sometimes it is reciever_id so I want to return the above relationship with the condition (if the receiver type in chat table is 1 it should be reciever_id else it should be the sender_id)
Controller
$seller_id = auth()->guard('seller')->user()->seller_id;
$chatLists = Admin::whereHas('chats', function ($q) {
$q->where('reciever_type', 2);
$q->orWhere('sender_type', 2);
})
->with(['chats' => function ($q) {
$q->where('reciever_type', 2);
$q->orWhere('sender_type', 2);
}])
->orderBy('created_at', 'desc')
->get();
return view('seller.chat.index', compact('chatLists'));
}
sender_type and receiver_type don't seem to do much.
If you retrieve $seller_id and intend to get all chats from $seller_id,
both chats with $seller_id as sender
and chats with $seller_id as receiver
Then your query could look like this.
$seller_id = auth()->guard('seller')->user()->seller_id;
$chatLists = Admin::whereHas('chats', function ($q) use ($seller_id) {
$q->where('receiver_id', $seller_id)
->orWhere('sender_id', $seller_id);
})
->with(['chats' => function ($q) use ($seller_id) {
$q->where('receiver_id', $seller_id)
->orWhere('sender_id', $seller_id);
}])
->latest()
->get();

How to return data from 2 tables with foreign keys in laravel

I am trying to return a view with 2 tables, orders and order_menu. What I want to do is to display what orders the customer ordered based on order_id to my view.
Here is the database table for orders and this is database table for order_menu.
I've tried using join table in my controller but it won't work. Here is my controller:
public function show(Order $order)
{
$data = DB::table('order_menu')
->join('menus', 'menus.id', '=', 'order_menu.menu_id')
->join('orders', 'orders.id', '=', 'order_menu.order_id')
->select('orders.*', 'menus.name', 'order_menu.quantity')
->get();
return view('admin.order.detail')->with([
'order' => $order,
'data' => $data,
]);
}
Is there any solutions to solve this?
You just need to add a filter for order id in your query, I assume $order is the instance of model and has order data
$data = DB::table('order_menu')
->join('menus', 'menus.id', '=', 'order_menu.menu_id')
->join('orders', 'orders.id', '=', 'order_menu.order_id')
->select('orders.*', 'menus.name', 'order_menu.quantity')
->where('orders.id', $order->id)
->get();
Or if you already have relations in place in your model then using eloquent you can query the data as
class Order extends Model
{
public function menus()
{
return $this->belongsToMany(Menu::class, 'order_menu ', 'order_id', 'menu_id')->withPivot('quantity');
}
}
class Menu extends Model
{
public function orders()
{
return $this->belongsToMany(Order::class, 'order_menu ', 'menu_id','order_id');
}
}
$data = Order::with('menus')->find($order->id);
public function show(Order $order)
{
$data = DB::table('orders*')
->join('order_menu*', 'order_menu.id', '=', 'orders.id')
->groupBy('orders.id')
->get();
return view('admin.order.detail')->with([
'data' => $data,
]);
}

Getting all related fields to related field in Eloquent

I have this DB structure:
classroom_user is Elqouent many-to-many pivot.
User.php:
public function classrooms() {
return $this->belongsToMany(ClassRoom::class, 'classroom_user', 'classroom_id', 'user_id');
}
ClassRoom.php:
public function users()
{
return $this->belongsToMany(User::class, 'classroom_user', 'user_id', 'classroom_id');
}
I have a $user and want to write Eloquent method which gets all users who are in at least one of classrooms the $useralso is in. Something like $user->classrooms->users. But this falls with error Property [users] does not exist on this collection instance.. How can I do this?
I think you can do it like this:
$users = User::whereHas('classrooms', function($query) {
$query->whereHas('users', function($query) {
$query->where('id', auth()->user()->id);
});
})->get();
You could store this as a scope in your User model:
public function scopeClassmatesOf($query, $user)
{
$query->whereHas('classrooms', function($query) use($user) {
$query->whereHas('users', function($query) use($user) {
$query->where('id', $user->id);
});
})
}
And then call it from a controller like:
$user = auth()->user();
$users = User::classmatesOf($user)->get();
Your asking for users of a collection. $user->classrooms is a collection of classrooms.
If you do $user->classrooms->first()->users you will get all the users from the first classroom.
To get all users from all classrooms, you can do something like;
$users = $user->classrooms->map(function ($classroom) {
return $classroom->users;
});
Note that will return duplicate users and authenticated user him self witin the collection. So, you might need to do some filtering to the result.
This worked for me:
public function classmates() {
$self = $this;
$a = User::with('classrooms')->whereHas('classrooms', function ($query) use ($self) {
$query->whereHas('users', function ($query) use ($self) {
$query->where('users.id', $self->id);
});
});
return $a;
}

Laravel - order by number of entries

This is a follow up from this question. I have a query that looks like this:
$users = User::leftjoin('role_user', 'users.id', '=', 'role_user.user_id')
->select('users.*')
->orderBy(DB::raw('role_id IS NULL'))
->groupBy('users.id')
->orderBy('role_id', 'asc')
->get();
When I do it like that I get distinct values for users, and they are ordered by role_id in asc order, the only thing with this query is that users that have two or more roles are behind the ones with who have only one role. For example, user has roles with id=1 and id=2, and other user has a only a role with id=1, that user will be before the user with two roles in the list. I would like to change that and have users with more roles above the ones with only one role.
I would recommend to use Query Scopes and Querying Relations
class User extends Authenticatable
{
...
public function roles()
{
return $this->belongsToMany('Role', 'role_user');
}
// Scope users who have a specified role
public function scopeHasRole($query, $role) {
return $query->whereHas('roles', function ($q) use ($role) {
$q->where('id', $role);
});
}
// Scope users who have a set of roles
public function scopeHasRoles($query, $roles) {
if (! is_array($roles)) {
return $this->scopeHasRole($query, $roles);
}
return $query->whereHas('roles', function ($q) use ($roles) {
$q->whereIn('id', $roles);
});
}
// Scope a user who don't have any roles.
public function scopeDoesntHaveAnyRoles($query) {
return $query->whereDoesntHave('roles');
}
}
Example usage:
User::doesntHaveAnyRoles(); // return users don't have any roles.
User::hasRole(1)->orderBy('id', 'asc')->get(); // return users who belongs to role id 1.
User::hasRoles([1, 2, 3]); // return users who have a set of roles.
Following query worked for me in the end:
User::leftjoin('role_user', 'users.id', '=', 'role_user.user_id')
->select('users.*')
->selectRaw('user_id, count(*) as count')
->orderBy(DB::raw('role_id IS NULL'))
->groupBy('users.id')
->orderBy('count', 'DESC')
->orderBy('role_id', 'asc')
->get();

Laravel query - get all users who post offer on admin user article

So as I write at title I need to get all users who post offer to an admin user article...
So I write:
public function userbase()
{
return Offer::select('users.*')
->where('users.admin', 9)
->join('articles','articles.id','=','offers.article_id')
->join('users','users.id','=','articles.user_id')
->where('articles.user_id', Auth::user()->id)
->orderBy('offers.created_at', 'desc')
->groupBy('users.id')
->get();
}
but I get just [] (which is not true) ...
I also try:
public function userbase()
{
$user_ids = Article::where('user_id', Auth::id())
->join('offers')->on('offers.article_id', '=', 'articles.id')
->join('users')->on('offers.user_id', '=', 'users.id')
->select('users.id')
->distinct()
->get();
$users = User::whereIn('id', $user_ids);
return $users;
}
but I get:
Missing argument 2 for Illuminate\Database\Query\Builder::join()
attempt was:
public function userbase() { $articles = Auth::user()->articles()->get(); foreach ($articles as $article) {
$offers = Offer::where('article_id', $article['id'])->orderBy('created_at', 'desc')->get();
}
foreach ($offers as $offer) {
$users = User::where('id', $offer['user_id'])->orderBy('created_at', 'desc')->get();
}
return $users;
}
but offcource dont work...
Now I really dont know what to do next... PLEASE HELP...
also my MODEL:
Article:
public function offers() {
return $this->hasMany('App\Offer');
}
Offer:
public function user() {
return $this->belongsTo('App\User');
}
public function article() {
return $this->belongsTo('App\Article');
}
So how I can get users who post offer to other user(admin) article...
Try to put this function in the User model:
public function scopeBase($query){
$sql = <<<SQL
id IN(
SELECT DISTINCT users.id FROM articles
INNER JOIN offers
ON articles.id=offers.article_id
INNER JOIN users
ON users.id=articles.user_id
WHERE articles.user_id=? AND users.admin=?
)
SQL;
return $query->whereRaw($sql, [$this->id, 9]);
}
Then in the controller to get the users use this syntax:
class MyController extends Controller{
public function example(){
$users = User::base()->get();
//....
}
}
However if you explain better the table structure you will be grateful.
Did you try this?
foreach (User::all() as $user) {
foreach ($user->offers as $offer) {
if ($offer->article->user->isAdmin())
$select[] = $user;
}
}

Categories