When condition on eloquent with the column values on the table - laravel

How can I add in conditional the value of the query i'm using on when function of eloquent laravel?
Here's what I want to happen
$user = User::when('logged' == '3', function ($q){
$q->where('role', 'admin');
)}->get();
As you can see I want to get the role admin only when the column logged is equal to 3 how can I do this one ? thank you.
P.S.
just an example query. thank you.

This is not how when works,
the first condition 'logged' == '3' will always return false;
So it will not use the closure query, directly use get() method, and return all the User's records;
You need to do it like this:
$user = User::where(function($q) {
$q->where(['logged' => 3, 'role' => 'admin'])
})->orWhere('logged', '!=', 3)->get();

You may only want to apply a where statement if a given input value is present on the incoming request. In short you first condition is not base on your table field but base on the request you have. So #TsaiKoga answer's is correct.
The when method only executes the given Closure when the first parameter is true. If the first parameter is false, the Closure will not be executed.
Please read docs here when

Related

How to change Laravel Auth::attempt method query?

I need to change the default Laravel query from Auth::attempt().
In the docs I saw two ways:
Pass more parameters to the Auth::attempt() method;
Create my own User provider.
The first solution not works for me, because I need to add a OR clause on the query (SELECT * FROM users WHERE email=? OR phone=?), and not an AND clause.
The second solution should be the correct one, but very complex, as I only need the retrieveByCredentials method.
Is there another way to make this?
Not sure if it's documented but you can do the following:
$givenField = '123456';
Auth::attempt([
'email' => function ($query) use ($givenField) {
$query->where('email', $givenField)
->orWhere('phone', $givenField)->from('users')->select('email');
]);
This is a bit hacky. It usually allows you to query other tables but here it's the same one

use a custom function inside a laravel select

I have a query that needs to use a custom function like is showed below.
The problem is that one of the parameters is a value of another field from the same query.
The function is "calcula_distancia" and "$ofps[0]->latitude" and "$ofps[0]->longitude" are fields from a previus query.
The function needs 4 parameters and the last two are field from $necps that is beeing selected, but I can not retrieve the value from it using just 'participantes.latitude' or even without cotes. It passes a string only, to the function.
So, how can I pass the value from this fields beeing selected to the function?
Tryed to use RAW but not work.
Sorry for the big question. thanks! :-)
use App\Classes\MinhasFuncoes;
$mf = new MinhasFuncoes();
$necps = DB::table('necessidades_part')->where('necessidades_part.id_part',"<>",$id_part)
->where(function($query) use ($searchValues){
foreach ($searchValues as $value) {
if(strlen($value)>3){
$query->orwhere('obs','like','%'.($value).'%')
->orwhere('necessidades.descricao','like','%'.($value).'%')
->orwhere('categorias.descricao','like','%'.($value).'%');
}
}
})
->join('participantes','necessidades_part.id_part','=','participantes.id')
->join('necessidades','necessidades_part.id_nec','=','necessidades.id')
->join('categorias','necessidades.id_cat','=','categorias.id')
->join('unidades','necessidades.id_unid','=','unidades.id')
->select('participantes.id as id_part','participantes.nome_part','participantes.latitude',
'participantes.longitude','participantes.nome_part','necessidades_part.id as id_nec_part',
'necessidades_part.id_nec','necessidades_part.quant','necessidades_part.data',
'necessidades_part.obs','necessidades.descricao as desc_nec',
'categorias.descricao as desc_cat','unidades.descricao as desc_unid',
$mf->calcula_distancia($ofps[0]->latitude,$ofps[0]->longitude,'participantes.latitude',
'participantes.longitude').' as distancia')
->orderBy('data','desc')
->paginate(10);
you can not execute your PHP function inside of your DB query. you should use MySQL function instead of that or you should fetch results from the database then map your result just in PHP

How to groupBy one column and count another column with condition in Laravel?

I have a table for students with column remarks which is equal to pass or fail and a column class to determine their group.
Now I want to get a collection using eloquent that goes like:
Select count(remarks) where 'remarks' equal to pass and
count(remarks) where 'remarks' equal to fail
GROUP BY class
What I have tried so far:
Student::where('remarks', 'pass')
->selectRaw('count(remarks) as passRemark')
->where('remarks', 'fail')
->selectRaw('count(remarks) as failRemark')
->groupBy('class')->get();
The above code doesn't seem to work and it returns nothing, it does work when using 1 where clause which is not what I intend to do and I tried adding another where, the query breaks.
Can anyone suggest the best approach for this?
To keep this in Eloquent, I would use the built in Laravel withCount() method and a closure function for each type of count.
Something like this would be my preference (I have now successfully tested this: each Student will have a count for both):
Student::withCount(['remarks as passRemark' => function ($query) {
$query->where('remarks', 'pass');
}, 'remarks as failRemark' => function ($query) {
$query->where('remarks', 'fail');
}])->groupBy('class')->get();
I guess you should try this query, using DB::raw(), just to see whether it works or not, then you can rewrite using the built in methods from the ORM.
SELECT SUM((CASE WHEN remarks = 'pass' THEN 1 ELSE 0 END)) AS passRemark,
SUM((CASE WHEN remarks = 'fail' THEN 1 ELSE 0 END)) AS failRemark
GROUP BY class

HasMany WhereNotIn

I am creating a query in laravel via models to filter out what is/isnt already in a group.
Models:
Group
GroupMembers
Users
Filters in place:
function members()
Groups->hasMany(GroupMembers)
Trying to achieve this:
Users->whereNotIn(Groups->members())
This is the lines of code in question, how the rest of it is all built I believe to be irrelevant:
$groups = Groups::find($request['id']);
// die($groups->members);
return view('admin.groups.add_member',
['group' => $groups,
'users' => User::whereNotIn('id', $groups->members->user)]);
the die() command returns the lines of the members successfully. The return statement groups->members returns an array of [1,1,1] (this is the group id where there are 3 members of the group)
I am sure its something simple but some help would be appreciated!
Try something like this (assuming the column is called user_id):
User::whereNotIn('id', $groups->members->pluck('user_id'))->get()

How to select specific columns in laravel eloquent

lets say I have 7 columns in table, and I want to select only two of them, something like this
SELECT `name`,`surname` FROM `table` WHERE `id` = '1';
In laravel eloquent model it may looks like this
Table::where('id', 1)->get();
but I guess this expression will select ALL columns where id equals 1, and I want only two columns(name, surname). how to select only two columns?
You can do it like this:
Table::select('name','surname')->where('id', 1)->get();
Table::where('id', 1)->get(['name','surname']);
You can also use find() like this:
ModelName::find($id, ['name', 'surname']);
The $id variable can be an array in case you need to retrieve multiple instances of the model.
By using all() method we can select particular columns from table like as shown below.
ModelName::all('column1', 'column2', 'column3');
Note: Laravel 5.4
You first need to create a Model, that represent that Table and then use the below Eloquent way to fetch the data of only 2 fields.
Model::where('id', 1)
->pluck('name', 'surname')
->all();
Also Model::all(['id'])->toArray() it will only fetch id as array.
Get value of one column:
Table_Name::find($id)->column_name;
you can use this method with where clause:
Table_Name::where('id',$id)->first()->column_name;
or use this method for bypass PhpStorm "Method where not found in App\Models":
Table_Name::query()->where('id','=',$id)->first()->column_name;
in query builder:
DB::table('table_names')->find($id)->column_name;
with where cluase:
DB::table('table_names')->where('id',$id)->first()->column_name;
or
DB::table('table_names')->where('id',$id)->first('column_name');
last method result is array
You can use get() as well as all()
ModelName::where('a', 1)->get(['column1','column2']);
From laravel 5.3 only using get() method you can get specific columns of your table:
YouModelName::get(['id', 'name']);
Or from laravel 5.4 you can also use all() method for getting the fields of your choice:
YourModelName::all('id', 'name');
with both of above method get() or all() you can also use where() but syntax is different for both:
Model::all()
YourModelName::all('id', 'name')->where('id',1);
Model::get()
YourModelName::where('id',1)->get(['id', 'name']);
To get the result of specific column from table,we have to specify the column name.
Use following code : -
$result = DB::Table('table_name')->select('column1','column2')->where('id',1)->get();
for example -
$result = DB::Table('Student')->select('subject','class')->where('id',1)->get();
use App\Table;
// ...
Table::where('id',1)->get('name','surname');
if no where
Table::all('name','surname');
If you want to get a single value from Database
Model::where('id', 1)->value('name');
Also you can use pluck.
Model::where('id',1)->pluck('column1', 'column2');
You can use Table::select ('name', 'surname')->where ('id', 1)->get ().
Keep in mind that when selecting for only certain fields, you will have to make another query if you end up accessing those other fields later in the request (that may be obvious, just wanted to include that caveat). Including the id field is usually a good idea so laravel knows how to write back any updates you do to the model instance.
You can get it like
`PostModel::where('post_status', 'publish')->get(['title', 'content', 'slug', 'image_url']`)
link
you can also used findOrFail() method here it's good to used
if the exception is not caught, a 404 HTTP response is automatically sent back to the user. It is not necessary to write explicit checks to return 404 responses when using these method not give a 500 error..
ModelName::findOrFail($id, ['firstName', 'lastName']);
While most common approach is to use Model::select,
it can cause rendering out all attributes defined with accessor methods within model classes. So if you define attribute in your model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Get the user's first name.
*
* #param string $value
* #return string
*/
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}
And then use:
TableName::select('username')->where('id', 1)->get();
It will output collection with both first_name and username, rather than only username.
Better use pluck(), solo or optionally in combination with select - if you want specific columns.
TableName::select('username')->where('id', 1)->pluck('username');
or
TableName::where('id', 1)->pluck('username'); //that would return collection consisting of only username values
Also, optionally, use ->toArray() to convert collection object into array.
If you want to get single row and from the that row single column, one line code to get the value of the specific column is to use find() method alongside specifying of the column that you want to retrieve it.
Here is sample code:
ModelName::find($id_of_the_record, ['column_name'])->toArray()['column_name'];
If you need to get one column calling pluck directly on a model is the most performant way to retrieve a single column from all models in Laravel.
Calling get or all before pluck will read all models into memory before plucking the value.
Users::pluck('email');
->get() much like ->all() (and ->first() etc..) can take the fields you want to bring back as parameters;
->get/all(['column1','column2'])
Would bring back the collection but only with column1 and column2
You can use the below query:
Table('table')->select('name','surname')->where('id',1)->get();
If you wanted to get the value of a single column like 'name', you could also use the following:
Table::where('id', 1)->first(['name'])->name;
For getting multiple columns (returns collection) :
Model::select('name','surname')->where('id', 1)->get();
If you want to get columns as array use the below code:
Model::select('name','surname')->where('id', 1)->get()->toArray();
If you want to get a single column try this:
Model::where('id', 1)->first(['column_name'])->column_name;

Resources