Laravel boolean validation based on others column - laravel

I want to validate the is_default column based on domain_id. The condition is for every domain_id there can be only one(single) 1; others multiple will be 0 (zero).
I try to make a rule in Laravel that's like the following. But It's not working; I know it's wrong. So what would be the best query?
$query = Restaurant::where($attribute, $value)
->where('domain_user.domain_id', request()->get('domain_id'));

Here is something you might want:
function updateDefault($domain_id, $name) {
//updating default domain with given name
Restoraunt::where('domain_id',$domain_id)->where('name', $name)->first()->update(['is_default' => 1]);
//setting all other models with same domain_id to 0
Restoraunt::where('domain_id', $domain_id)->where('name', '!=', $name)->update(['is_default' => 0]);
}
If you for example use updateDefault(1, 'ABC - 2') results would be :

Related

Eloquent count occurrence with where clause

I'm trying to do a simple query using Eloquent. My test_registrants table looks like this
I want to add new column with value of all user_id with payment_status = 1
This is my query using whereColumn
TestRegistrant::select(['test_registrants.*'])
->where('payment_status', 1)
->addSelect([
'attempt' => TestRegistrant::select(DB::raw('count(*) as attempt'))
->whereColumn('test_registrants.user_id', 'user_id')
->where(function ($query) {
$query->where('payment_status', 1);
})
]);
but I get all user_id instead
What I'm trying to achieve is this one
So what do I do wrong here? thank you
The reason your query is returning 3, is because it is simply counting all the records that have payment_status = 1. The whereColumn() is not working properly, because it does not reflect the right columns.
When you define an alias for the user_id column on the test_registrants table, it should work. For example, you could name it: outer_user_id. I have updated your example accordingly:
TestRegistrant::select(['test_registrants.payment_status', 'test_registrants.user_id as outer_user_id'])
->where('payment_status', 1)
->addSelect([
'attempt' => TestRegistrant::selectRaw('count(*) as attempt')
->whereColumn('test_registrants.user_id', 'outer_user_id')
->where(function ($query) {
$query->where('payment_status', 1);
})
])
->get();
Alternatively, you could also look into grouping the results, so that you can count all the rows in a specific group.

Update multiple rows at once Laravel Eloquent

I have the table products with the following structure.
id | name | promote
Where the column promote is of boolean type.
I want to set the value of the boolean column to 1 with the selected rows and set 0 to non-selected rows. I have the following code in the controller to handle this query.
$yes = Tour::whereIn('id', $request->promote)->get();
$no = Tour::whereNotIn('id', $request->promote)->get();
foreach ($yes as $item) {
$item->promote = 1;
$item->save();
}
foreach ($no as $item) {
$item->promote = 0;
$item->save();
}
I get following from the form request.
The above code does work but it isn't very efficient I assume. I'm looking for optional ways to achieve the result in a more efficient way.
Instead retrieving result, looping through, you can update directly,
$yes = Tour::whereIn('id', $request->promote)->update(['promote' => 1]);
$no = Tour::whereNotIn('id', $request->promote)->update(['promote' => 0]);
If you don't care about going through the Model to do the updating you can call update on the builder to update all the matched records. As this will use the builder and not the Model there will not be any model events fired:
// set them all to promote = 0
Tour::update(['promote' => 0]);
// or just set the ones that need to be 0
Tour::whereNotIn('id', $request->promote)->update(['promote' => 0]);
// set the ones you want to promote = 1
Tour::whereIn('id', $request->promote)->update(['promote' => 1]);
Just one way to give it a go.

Laravel Model::find() auto sort the results by id, how to stop this?

$projects = Project::find(collect(request()->get('projects'))->pluck('id')); // collect(...)->pluck('id') is [2, 1]
$projects->pluck('id'); // [1, 2]
I want the result to be in the original order. How do I achieve this?
Try $projects->order_by("updated_at")->pluck("id"); or "created_at" if that's the column you need them ordered by.
Referencing MySQL order by field in Eloquent and MySQL - SELECT ... WHERE id IN (..) - correct order You can pretty much get the result and have it order using the following:
$projects_ids = request()->get('projects'); //assuming this is an array
$projects = Project::orderByRaw("FIELD(id, ".implode(',', projects_ids).")")
->find(projects_ids)
->pluck('id'));
#Jonas raised my awareness to a potential sql injection vulnerability, so I suggest an alternative:
$projects_ids = request()->get('projects');
$items = collect($projects_ids);
$fields = $items->map(function ($ids){
return '?';
})->implode(',');
$projects = Project::orderbyRaw("FIELD (id, ".$fields.")", $items->prepend('id'))
->find($projects_ids);
The explanation to the above is this:
Create a comma separated placeholder '?', for the number of items in the array to serve as named binding (including the column 'id').
I solve this by querying the data one by one instead mass query.
$ids = collect(request()->get('projects'))->pluck('id');
foreach($ids as $id){
$projects[] = Project::find($id);
}
$projects = collect($projects);
$projects->pluck('id');
I have to do this manually because laravel collection maps all the element sorted by using ids.

Codeigniter Query binding multiple fields with the same value

I'm in a situation where I'm doing a MySQL query with Codeigniter and where I have a lot of fields value request which are ALL the same.
Example:
$this->db->query('SELECT * FROM abc WHERE user_id = ? AND msg_from = ? AND msg_to != ?', [$id, $id, $id]);
This has just 3 question marks but the query I'm working on is HUGE and has 19 question marks WHICH ARE ALL THE SAME variable.
So I was trying to figure out how to tell Codeigniter all question marks are pointing to the same variable without having to fill an array with 19 times the same variable.
I thought of a for-loop but I wanted to know if a shortcut exist.
you should be able to do this with Codeigniters Query Builder pretty easily
Something like that should work:
$this->db
->select('*')
->from('abc');
$arrFields = array('users_id', 'msg_from', 'msg_to');
foreach($arrFields AS $val)
{
$this->db->where($val, $id);
}
$query = $this->db->get();

What is the equivalent query of laravel on this?

This is the native sql:
$sql = "Select count(name) from users Where email = 't#t.com' and user_id = 10";
I have this laravel code:
$checker = Customer::whereEmailAndUserId("t#t.com",10)->count("name");
Is this a correct way to do it in laravel?
You have to use where helper function and pass an array of checks. For example in your code it will be:
$checker = Customer::where([
['email', '=', 't#t.com'],
['user_id' '=', '10']
])->count();
Note: Please use the appropriate column name as it in table.
Assuming Customer model represents table users, you'll get query with eloquent like this:
Customer::where('email', 't#t.com')->where('user_id', 10)->select(\DB::raw('count(name)'))->get();
The option you are trying is incorrect
here is the right option
$users = \App\Customer::where('email','t#t.com')
->where('user_id',10)
->count()
Explanation of above code
App\Customer is the Model class and I am trying to read records where email = 't#t.com you can use various comparison operators like <,> and so on and you can also use the same function to for string pattern matching also
Eg.
$users = \App\Customer::where('email','%t.com')
->where('user_id',10)
->count()
You can use the same where function for Null Value test also
Eg.
$users = \App\Customer::where('email','=', null)
->where('user_id',10)
->count()
The above where clause will be converted to is null test of the SQL
You can read more here

Resources