Laravel query not working properly - php

I do have simple query working properly but I want it working properly using ORM.
I have the following SQL query:
SELECT career_solutions.*,
users.username,
users.profile_picture
FROM career_solutions
INNER JOIN users
ON users.id = career_solutions.user_id
INNER JOIN privacy_settings
ON privacy_settings.user_id = users.id
WHERE career_solutions.topic_category_id = $categoryid
AND ( ( privacy_settings.career_solutions = 0
AND public = 1 )
OR (( users.id IN (SELECT contacts.contact_id
FROM contacts
WHERE contacts.user_id = $id)
OR users.id = $id )) )
ORDER BY date DESC
LIMIT 5000
I'm passing the query directly to to the select method of the DB Facade like so:
DB::select($aboveQuery); and it's working fine.
I am trying to do same using Laravel Eloquent.
By using the following code I am not getting same result as above. Something is wrong with the below query.
$career_solution = CareerSolution::with('user.role', 'user.privancy_setting', 'category', 'sub_category', 'country');
$career_solution = $career_solution->where(function ($query) {
$query->where('expires_at', '>=', date('Y-m-d'))
->orWhere('expires_at', '=', '0000-00-00');
});
$career_solution = $career_solution->Where(function ($query1) use ($id) {
$query1->Where(function ($query2) use ($id) {
$query2->whereHas('user.privancy_setting', function ($query3) {
$query3->where('privacy_settings.career_solutions', '=', 0);
})->where('public', '=', 1);
})->orWhere(function ($query4) use ($id) {
$query4->whereHas('user.contact', function ($query5) use ($id) {
$query5->where('contacts.user_id', '=', $id);
})->orWhere('user_id', '=', $id);
});
});
It is not showing same result as above, let me know how I make it same as above.

The where condition are not used correctly, could you try this:
$career_solution = CareerSolution::with('user.role', 'user.privancy_setting', 'category', 'sub_category', 'country');
$career_solution = $career_solution->where(function ($query) {
$query->where('expires_at', '>=', date('Y-m-d'))
->orWhere('expires_at', '=', '0000-00-00');
});
$career_solution = $career_solution->where(function ($query1) use ($id) {
$query1->where(function ($query2) use ($id) {
// assuming that the relation name in User model is name public function privacy_setting ..
$query2->whereHas('user.privacy_setting', function ($query3) {
$query3->where('career_solutions', '=', 0); // You don't need to specify the table here only the table field you want
})->where('public', '=', 1);
})->orWhere(function ($query4) use ($id) {
// idem here the relation must be name contact
$query4->whereHas('user.contact', function ($query5) use ($id) {
$query5->where('user_id', '=', $id); // idem here
})->orWhere('user_id', '=', $id);
});
});

Related

I am trying to fetch messages from databse in larvavel (little stuck)

I am tying to make a chat app in laravel. I am trying to fetch one to one messages.
Heres my controller:-
public function user( $id) {
$chat = User::find($id);
$table = DB::table('messages')
->where('sender', Auth::user()->id, '&&', 'reciever', $id)
->orWhere('sender', $id, '&&', 'reciever', Auth::user()->id)
->get();
return view('user', compact('chat', 'id', 'table'));
}
My messages Migration:-
public function up()
{
Schema::create('messages', function (Blueprint $table) {
$table->id();
$table->integer('sender')->unsigned();
$table->integer('reciever')->unsigned();
$table->text('message');
$table->timestamps();
});
}
Here's the route:- Route::get('/user/{id}', 'ContactsController#user');
This is the error that I am getting:-
SQLSTATE[HY000]: General error: 1 near ""sender"": syntax error (SQL: select * from "messages" where reciever "sender" = 30 "sender" = 1)
I think there is something wrong with my logic, can anyone guide me.
Please see https://laravel.com/docs/7.x/queries#parameter-grouping for information on query groupings. You need to separate out your logic like this
$table = DB::table('messages')
->where(function($query) use ($id) { // Where (sender = User AND receiver = id)
$query->where('sender', Auth::user()->id)
->where('reciever', $id);
})
->orWhere(function($query) use ($id) { // OR (sender = id AND receiver = User)
$query->where('sender', $id)
->where('reciever', Auth::user()->id);
})
->get();
The problem is with your where() and orWhere()
->where('sender', Auth::user()->id, '&&', 'reciever', $id)
->orWhere('sender', $id, '&&', 'reciever', Auth::user()->id)
What you should do instead:
->where([
['sender', Auth::user()->id],
['reciever', $id],
])->orWhere([
['sender', $id],
['reciever', Auth::user()->id],
])
I suggest reading Laravel Where Clauses docs before diving in.
This worked for me:-
$messages = Message::where('sender', $id)->orWhere('reciever', $id)->get();
$messages = Message::where(function($q) use ($id) {
$q->where('sender', auth()->id());
$q->where('reciever', $id);
})->orWhere(function($q) use ($id){
$q->where('sender', $id);
$q->where('reciever', auth()->id());
})
->get();

Trying to search in a model via eloquent - laravel with optimal parameters

Im trying to figure out why my query is ignoring everything except the title and the description. The search button leading to the controller, is for filtering different type of ads , by category, by region, by price.
For example if now i search for existing ad and its found by title / keyword -> will always show, even if i choose a different region / category/ price range
Im trying to use something that will save me a lot of if statements to check if they exist in the request. Maybe other option si to use https://github.com/mohammad-fouladgar/eloquent-builder to build my query
public function index(Request $request)
{
$keyword = $request['keyword'];
$category_id = $request['category_id'];
$type_id = $request['type_id'];
$region_id = $request['region_id'];
$min_price = $request['min_price'];
$max_price = $request['max_price'];
$result = Ad::when($keyword, function ($q) use ($keyword) {
return $q->where('title', 'like', '%' . $keyword . '%')->orWhere('description', 'like', '%' . $keyword . '%');
})
->when($category_id, function ($q) use ($category_id) {
return $q->where('category_id', $category_id);
})
->when($region_id, function ($q) use ($region_id) {
return $q->where('region_id', '=', $region_id);
})
->when($type_id, function ($q) use ($type_id) {
return $q->where('adtype_id', '=', $type_id);
})
->when($min_price, function ($q) use ($min_price) {
return $q->where('price', '>=', $min_price);
})
->when($max_price, function ($q) use ($max_price) {
return $q->where('price', '<=', $max_price);
})
->paginate(8);
My get param url looks like that:
search?keyword=&category_id=0&region_id=0&type_id=0&min_price=&max_price=
The produced query in mysql when i search for existing ad by its name and i look for a different category is:
select * from `ads` where `title` like '%test test%' or `description` like '%test test%' and `category_id` = '2' limit 8 offset 0
The ad is found, but the actual category is 1, not 2, same for all others optimal parameters.
You can edit your query to look for specific relations, using whereHas. This method will allow you to add customized constraints to a relationship constraint, such as checking the content of a comment.And to check max/min price, use where method. So, you can use it like this:
$result = Ad::when($keyword, function ($q) use ($keyword) {
return $q->where('title', 'like', '%' . $keyword . '%')->orWhere('description', 'like', '%' . $keyword . '%');
})
->whereHas('category_relation_name', function ($q) use ($category_id) {
return $q->where('category_id', $category_id);
})
->whereHas('region_relation_name', function ($q) use ($region_id) {
return $q->where('region_id', $region_id);
})
->whereHas('type_relation_name', function ($q) use ($type_id) {
return $q->where('adtype_id', $type_id);
})
->where('price', '>=', $min_price);
->where('price', '<=', $max_price);
->paginate(8);

Laravel eloquent chunk method return all the time false or null

I am using Laravel v4.2. I want to delete conversation between two users but Now I want that If one user delete the conversation than other user can view the conversation until second user also delete the conversation.
For this I have two column to delete conversation name "delete_on" and "delete_two". For this purpose I am using eloquent chunk method which always return false or null.
$return = Message::where('message_to', '=', $userData['id'])
->where('message_from', '=', $userData['message_from'])
->orwhere(function($query) use($userData) {
$query->where('message_to', '=', $userData['message_from'])
->where('message_from', '=', $userData['id']);
})->chunk(100,function($messages) use($userData){
foreach ($messages as $msg){
if(empty($msg->delete_one)){
$msg->delete_one = $userData['id'];
}else{
$msg->delete_two = $userData['id'];
}
if($msg->save()){
}
}
});
To know more about chunk() refer to this answer mentioned in the comments Thanks Gokigooooks for the acknowledgement.
The syntax you need to employ is the following for in your case it's eloquent:
Eloquent
For first of all check whether you are getting chunk result here like this:
Message::where('message_to', '=', $userData['id'])
->where('message_from', '=', $userData['message_from'])
->orwhere(function($query) use($userData) {
$query->where('message_to', '=', $userData['message_from'])
->where('message_from', '=', $userData['id']);
})->chunk(100,function($messages) use($userData){
foreach ($messages as $msg){
dd($msg); or print_r($msg);
}
});
Now try this
$return = Message::where('message_to', '=', $userData['id'])
->where('message_from', '=', $userData['message_from'])
->orwhere(function($query) use($userData) {
$query->where('message_to', '=', $userData['message_from'])
->where('message_from', '=', $userData['id']);
})->chunk(100,function($messages) use($userData){
foreach ($messages as $msg){
if(empty($msg->delete_one)){
$msg->delete_one = $userData['id'];
}else{
$msg->delete_two = $userData['id'];
}
$msg->save();
}
});

How to include or exclude where statement in Laravel Eloquent

I need the same query for two different user roles. Difference is only in one whereNotIn condition.
So for the Basic user it would be:
$chart2 = DB::connection('mysql2')->table('tv')
->select('*')
->join('epgdata_channel', 'cid', '=', 'channelid')
->where('ReferenceDescription', $campaign->spotid)
->whereNotIn('ChannelName', $sky)
->get();
And for Premium:
$chart2 = DB::connection('mysql2')->table('tv')
->select('*')
->join('epgdata_channel', 'cid', '=', 'channelid')
->where('ReferenceDescription', $campaign->spotid)
->get();
I know I can do it with simple if statement:
if($user->userRole == "Basic"){
//first $chart2
}
else{
//second $chart2}
but I have a lots of queries where I need just to add or remove this whereNotin condition and rewriting the queries (using if statement) is not a nice solution.
Try scope.
In your TVModel.php:
public function scopeConditionalWhereNotIn($query, $doesUse, $col, $val) {
if($doesUse)
$query->whereNotIn($col, $val);
}
Usage:
$condi = true;//or false.
$chart2 = TVModel::select('*')
->join('epgdata_channel', 'cid', '=', 'channelid')
->where('ReferenceDescription', $campaign->spotid)
->conditionalWhereNotIn($condi, 'ChannelName', $sky)
->get();
Inside your model add this:
public function scopeBasicUser($query,$channel){
return $query->whereNotIn('ChannelName', $channel);
}
and in your controller:
$query = DB::connection('mysql2')->table('tv')
->select('*')
->join('epgdata_channel', 'cid', '=', 'channelid')
->where('ReferenceDescription', $campaign->spotid);
if($user->userRole == "Basic")
$query = $query->basicUser($channel);
return $query->get();
$userRole = $user->userRole;
$chart2 = DB::connection('mysql2')->table('tv')
->select('*')
->join('epgdata_channel', 'cid', '=', 'channelid')
->where('ReferenceDescription', $campaign->spotid)
->where(function ($query) use ($userRole){
if($userRole == "Basic"){
$query->whereNotIn('ChannelName', $sky)
}
})
->get();
This code worked for me.

Laravel/Eloquent: Add missing () in sql statements generated by eloquent

I am doing the following request to extract some data from my database. The expected result is wrong because some parenthesis is not well placed in the SQL generated request:
$data = Ov::with([
'masters' => function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->whereIn('macAddress', $devicesArrayOnlyLKUAToZero)
->orWhere('lastKnownUpAt','<>', '0');
}
])->where('ovId', '=', $ovId)->get();
The dedicated sql generated by Laravel is: (see with Laravel debugbar):
select * from `masterequipments` where `masterequipments`.`id_ov_foreign_key` in ('38') and `macAddress` in ('e8:e7:32:c1:e6:48', 'e8:e7:32:bc:b0:94', 'e8:e7:32:e4:8e:68', 'e8:e7:32:bc:a7:70', '00:e0:b1:fe:ef:a5', 'e8:e7:32:bc:a7:a4', '2c:fa:a2:10:79:74', 'e8:e7:32:b9:6d:1d', '00:e0:b1:ee:58:2d', '00:e0:b1:9d:2c:44', '00:e0:b1:b5:e6:00', '00:e0:b1:72:34:86', '00:e0:b1:fe:ee:8d', '00:e0:b1:79:53:52', '00:e0:b1:fe:f0:bd', '00:e0:b1:75:fa:8a', 'e8:e7:32:98:80:22', '00:e0:b1:75:00:8a') or `lastKnownUpAt` <> '0'
This is wrong because 2 () are missed. I would like to have:
select * from `masterequipments` where `masterequipments`.`id_ov_foreign_key` in ('38') and (`macAddress` in ('e8:e7:32:c1:e6:48', 'e8:e7:32:bc:b0:94', 'e8:e7:32:e4:8e:68', 'e8:e7:32:bc:a7:70', '00:e0:b1:fe:ef:a5', 'e8:e7:32:bc:a7:a4', '2c:fa:a2:10:79:74', 'e8:e7:32:b9:6d:1d', '00:e0:b1:ee:58:2d', '00:e0:b1:9d:2c:44', '00:e0:b1:b5:e6:00', '00:e0:b1:72:34:86', '00:e0:b1:fe:ee:8d', '00:e0:b1:79:53:52', '00:e0:b1:fe:f0:bd', '00:e0:b1:75:fa:8a', 'e8:e7:32:98:80:22', '00:e0:b1:75:00:8a') or `lastKnownUpAt` <> '0')
Use advanced where clauses to accomplish it.
$data = Ov::with([
'masters' => function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->where(function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->whereIn('macAddress', $devicesArrayOnlyLKUAToZero);
})
->orWhere(function($query) {
$query->where('lastKnownUpAt','<>', '0');
});
}
])->where('ovId', '=', $ovId)->get();
UPDATE
$data = Ov::with([
'masters' => function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->where(function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->whereIn('macAddress', $devicesArrayOnlyLKUAToZero);
})
->orWhere('lastKnownUpAt','<>', '0');
}
])->where('ovId', '=', $ovId)->get();
Yo need to do something like this:
$data = Ov::with([
'masters' => function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->where(function ($query) use ($devicesArrayOnlyLKUAToZero) {
$query->whereIn('macAddress', $devicesArrayOnlyLKUAToZero);
})
->orWhere(function($query) {
$query->where('lastKnownUpAt','<>', '0');
});
}
])->where('ovId', '=', $ovId)->get();
This article explain it well http://laraveldaily.com/and-or-and-brackets-with-eloquent/

Categories