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();
Related
Anyone can help me? How to add where condition from the with function model relation.
I tried ->where('driver.group_id',$group_id) but it does not work. please look my code below.
public function getDriversDailyEarnings()
{
$group_id = Auth::user()->group->id;
$today = Carbon::today();
$data = DailyEarnings::with(['payout_cost',
'status:id,name',
'driver' => function ($query) {
$query->with('user');
}])
->where('driver.group_id',$group_id)
->whereDate('created_at', $today)
->get();
return response()->json($data, 200);
}
You can try this. Haven't tested it yet.
DailyEarnings::with([
'payout_cost',
'status:id,name'
'driver' => function($query) {
$query->where('group_id', auth()->user()->group->id)->with('user');
}
])
->whereHas('driver', function($query) {
$query->where('group_id', auth()->user()->group->id);
})
->whereDate('created_at', now()->format('Y-m-d'))
->get();
To pass other clauses to a relation, just use it inside an array, where the key and the name of the relation and the value is a function that receives an instance of the query, something like this:
public function getDriversDailyEarnings()
{
$data = DailyEarnings::with([
'payout_cost' => function ($myWithQuery) {
$myWithQuery->where('column-of-relation-here', 'value-here')
->orWhere('name', 'LIKE', '%Steve%');;
}
])->get();
return response()->json($data, 200);
}
Perhaps something like this:
// ->where('driver.group_id',$group_id)
->whereHas('driver', fn($qry) => $qry->where('group_id', $group_id)) // if group_id a field on driver
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();
}
});
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);
});
});
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.
I would like to assign a group to users which have a role student and have also a particular selected group. There is a users table, which has pivot tables: role_user and group_user with roles and groups tables. Below is the code for the controller where I am trying to execute the query:
$this->validate($request, [
'add-group' => 'required',
'where-group' => 'required'
]);
$selectedGroup = $request->input('add-group');
$whereGroupId = $request->input('where-group');
$users = User::whereHas('roles', function($q) {
$q->where('name', 'student');
})->whereHas('groups', function($q) {
$q->where('id', $whereGroupId);
})->get();
$selectedGroup = Group::whereId($selectedGroup)->first();
$users->assignGroup($selectedGroup);
You need to use the orWhereHas clause for the second half of the query.
Secondly, your $whereGroupId variable is not in the inner-function's scope, add a use($whereGroupId) statement to include it in the function's scope.
$users = User::whereHas('roles', function($q) {
$q->where('name', 'student');
})->orWhereHas('groups', function($q) use ($whereGroupId) { // <-- Change this
$q->where('id', $whereGroupId);
})->get();
You had syntax error and a missing use to pass whereGroupId. I have no clue what assignGroup does, but this should fix the code you have.
$this->validate($request, [
'add-group' => 'required',
'where-group' => 'required'
]);
$selectedGroup = $request->input('add-group');
$whereGroupId = $request->input('where-group');
$users = User::whereHas('roles', function ($q) {
$q->where('name', 'student');
})
->whereHas('groups', function ($q) use ($whereGroupId) {
$q->where('id', $whereGroupId);
})->get();
$selectedGroup = Group::whereId($selectedGroup)->first();
$users->assignGroup($selectedGroup);