Add join filter in Laravel Eloquent - php

I am a novice in Laravel.
I want to add a filter join through Laravel Eloquent model.
I have below relationship
user belongs to city
user has one restaurant
restaurant has many jobs
Now I want to fetch all jobs with a filter of city.
I tried couple of ways, but ended up in error, like:
$jobs = Job::where("date_time", ">=", $currentDate)->where("city.id", 50)->whereIn('job_status', ['upcoming', 'active'])->orderBy('start_date_time', 'desc')->get();
and the below one
$jobs = Job::with(['restaurant'])->where("date_time", ">=", $currentDate)->where("city.id", 50)->whereIn('job_status', ['upcoming', 'active'])->orderBy('start_date_time', 'desc')->get();
So, here how can I add join from job -> restaurant -> user -> city?
Thanks

Assuming you have city_id in your table
$jobs = DB::table('jobs')->with('restaurant')
->join('users', 'users.id', '=', 'restaurant.user_id')
->join('cities', 'users.id', '=', 'cities.user_id')
->where("table_name.date_time", ">=", $currentDate)
->where("cities.id", 50)
->whereIn('job_status', ['upcoming', 'active'])
->orderBy('table_name.start_date_time', 'desc')->get();
I have edited my answer hope it helps. If not please post your errors and table structure.
You can read about joins here: https://laravel.com/docs/6.x/queries#joins

Related

Using multi where queries Laravel relationships

I have two tables (Table1, Table2).
I want to print the sum of the records whose properties match Table1 in Table2 while listing the Table1 table.
My two tables contain very large records, performance is important to me.
// Model -> relationships
public function cars()
{
return $this->hasMany('App\Models\Table2', 'list_id', 'list_id');
}
// Controller
$table1 = Table1::with('cars' => function($query){
$query->where('table2.color','=', 'table1.color')
$query->where('table2.year','=', 'table1.year')
}])
->get();
I'm adding the sample database pictures:
Thank you.
First, add below use statement to the top of your controller:
use DB;
Now, If you only want to get the records amount, you can do this:
$amount = DB::table('table1')
->join('table2', function($join){
$join->on('table1.color', '=', 'table2.color');
$join->on('table1.year', '=', 'table2.year');
})->count();
But if you want to get the list of the table1 records, you can change the query a bit like below:
$records = DB::table('table1')
->select('table1.*')
->join('table2', function($join){
$join->on('table1.color', '=', 'table2.color');
$join->on('table1.year', '=', 'table2.year');
})->count();
Please follow Laravel's official guide on this topic:
https://laravel.com/docs/8.x/queries#advanced-join-clauses
Use join to merge the two tables read more about join here https://www.w3schools.com/sql/sql_join.asp

Laravel append data count to database object

Hello i have this function
public function readData(){
$TableB1 = \DB::table('users')
->join('group_user', 'users.id', '=', 'group_user.user_id')
->join('groups', 'groups.id', '=', 'group_user.group_id')
->join('meetings', 'users.id', '=', 'meetings.owned_by_id')
->select(
'users.name as name',
'group_user.user_id as id',
'groups.name as groupname',
)
->get();
foreach ($TableB1 as &$data){
$meetings = \DB::table('meetings')
->where('company_id', 1)->where('owned_by_id', $data->id)
->where(\DB::raw('MONTH(created_at)'), Carbon::today()->month);
echo $meetings->count();
}
return $TableB1;
}
i retrieve some data from database and return them and use AJAX Call to use them later
The problem is i have a table called users and table called meetings
i want to know how many meetings every user done everyday
so to do this i made a for each to take the user_id and use it to get the count
of meetings done by each user
for example in meetings table i have a owned_by_id field which have the user_id
so what the code does if it found for example if owned_by_id(6) repeated in
meetings table 4 times it will return 4
but this is what i get in the browser
instead what i want to get is something like this
im using Laravel 5.7 and sorry i know my question is unclear this is the 1st time i have ever asked question on stackoverflow
Image
If you want count of meetings then you may use laravel eloquent method with is: withCount();
Like this:
$users = User::with('meetings')->withCount('meetings')->get();
If you will do this then you will get meetings_count with your user object.
And if you have still any doubt you may refer following link:
https://laravel.com/docs/5.8/eloquent-relationships
Thnak you!
You could add a new column in the select() using the COUNT SQL statement:
->select(
'users.name as name',
'group_user.user_id as id',
'groups.name as groupname',
\DB::raw('(
SELECT COUNT(meetings.id) FROM meetings GROUP BY meetings.owned_by_id
) as meetings')
)

List all users and their recipes

I'm writing a custom database query in Laravel for my cocktail app. The goal is to retrieve the following structure:
User 1
Recipe 1
Recipe 4
User 2
Recipe 2
Recipe 3
etc...
My code (see below) currently returns 3 objects, all containing a single recipe but all from 2 users. Is it even possible to build the desired structure (see above), retrieving a user and having his/her recipes stored in a array/object called recipes?
$recipes = DB::table('users')
->join('recipes', 'users.id', '=', 'recipes.user_id')
->select(
'recipes.id as recipe_id',
'recipes.name as recipe_name',
'recipes.short as short',
'users.name as user_name'
)
->get();
While in Laravel, use Eloquent.
In your User model add relationship to recipes:
public function recipes()
{
return $this->hasMany('App\Recipe');
}
To call it:
$recepies = App\User::find(1)->recipes;
https://laravel.com/docs/5.6/eloquent-relationships
You cannot get this format using query.
First fetch users then fetch recipes.
Then format them using loop.
OR
Use eloquent :)
$recepies = App\User::with('recipes')->get();
I think this would work
$recipes = DB::table('users')
->select(
'recipes.id as recipe_id',
'recipes.name as recipe_name',
'recipes.short as short',
'users.name as user_name'
)
->where('recipes.user_id', '=', 'users.id')
->get();

Laravel Complex Query

I am new to Laravel and building a small Laravel 5.3 app offering free content files as well as files for purchase.
I want users to automatically have access to the free files (content which may be added periodically).
I have a products, purchases (pivot) and users table.
When a user is logged in, how can I query the products table like the following: select all free products (price=0) or join on purchases where users.user_id = purchases.user_id and products.id = purchases.product_id?
Any ideas, or is there a better way to accomplish the same thing?
Thanks
How about if you use following query:
$purchasedProducts = DB::table('purchases')
->join('products', 'products.id', '=', 'purchases.product_id')
->select('purchases.*', 'products.*')
->where([
['purchases.user_id', '=', $loggedinUserId],
['products.price', '=', 0],
])
->get();
If you have defined the relations between user and product then you can query it using orWhereHas as:
Product::where('price', 0)
->orWhereHas('users', function ($q) user($user) {
$q->where('user_id', $user->id);
})
->get();
Assuming your relation name is users.

Laravel 5.1: handle joins with same column names

I'm trying to fetch following things from the database:
user name
user avatar_name
user avatar_filetype
complete conversation_messages
with the following query:
static public function getConversation($id)
{
$conversation = DB::table('conversation_messages')
->where('belongsTo', $id)
->join('users', 'conversation_messages.sender', '=', 'users.id')
->join('user_avatars', 'conversation_messages.sender', '=', 'user_avatars.id')
->select('users.name', 'conversation_messages.*', 'user_avatars.name', 'user_avatars.filetype')
->get();
return $conversation;
}
It works fine so far, but the avatar's column name is 'name' like the column name from the 'users' table.
So if I'm using this query the to get the output via $conversation->name, the avatar.name overwrites the users.name
Is there a way to rename the query output like the mysql "as" feature at laravel 5.1?
For example:
$conversation->avatarName
$conversation->userName
Meh okay.. i've found a simple solution here
->select('users.name as userName', 'conversation_messages.*', 'user_avatars.name as avatarName', 'user_avatars.filetype')
As you can mention I've added the requested "as-Feature" next to the table.columnName
Take a look at this example of trying to join three tables staffs, customers and bookings(pivot table).
$bookings = \DB::table('bookings')
->join('staffs', 'staffs.id' , '=', 'bookings.staff_id')
->join('customers', 'customers.id' , '=', 'bookings.customer_id')
->select('bookings.id', 'bookings.start_time', 'bookings.end_time', 'bookings.service', 'staffs.name as Staff-Name', 'customers.name as Customer-Name')
->orderBy('customers.name', 'desc')
->get();
return view('booking.index')
->with('bookings', $bookings);
I had the following problem, simplified example:
$result = Donation::join('user', 'user.id', '=', 'donation.user_id')->where('user.email', 'hello#papabello.com')->first();
$result is a collection of Donation models. BUT CAREFUL:
both tables, have a 'created_at' column. Now which created_at is displayed when doing $result->created_at ? i don't know. It seems that eloquent is doing an implicit select * when doing a join, returning models Donation but with additional attributes. created_at seems random. So what I really wanted, is a return of all Donation models of the user with email hello#papabello.com
solution is this:
$result = Donation::select('donation.*')->join('user', 'user.id', '=', 'donation.user_id')->where('user.email', 'hello#papabello.com')->first();
Yeah, simply rename the column on either table and it should work.
Also what you can do is, rename the user.name column to anything, also rename sender column of conversation_messages to id and perform a natural join.

Categories