Laravel Eloquent apply search condition to all requests - laravel

In Laravel Eloquent, there is a concept called "Soft Deletes" where a record is "Deleted" from the database. It's not actually deleted, there is only a date added to the "deleted_at" field. This means that almost any request, other than those that specify searching for soft deleted records, will not return those records, even if they match the criteria of the original request.
Is there a way to do something similar for other values? For example, if I have a column in the table called "is_ready", no search request will return a record unless that record has "is_ready" set to true, even if all other conditions are met.
This is something that has to apply to all requests made though this model over a large quantity of different queries, so it's not feasible to add that condition to all queries individually.

Related

Laravel get collection of created/updated rows

new to laravel.
My use case:
Update multiple rows (say: resources table).
Create multiple users (users table).
Retrieve ids of created users
What I currently did:
First, Update the resources table whereIn('id', [1,2,3,4]). (Update eloquent)
Second, Get array of the updated resources (Another eloquent: Resource::whereIn('id', [1,2,3,4])->get()->toArray())
Bulk create a users. Refers to the resources collection above. (Another eloquent: User::create($resources))
Lastly, get the ids of the created users (Not resolved yet. But I might have to use another eloquent query)
All in all, there are 4 Eloquent queries, which I want to avoid, because this might have performance issue.
What I wanted to do is that, On first step(Update), I should be able to get a collection of models of the affected rows (But I can't find any reference on how to achieve this). And then use this collection to create the users, and get the users ids in one query with User::create() so that I will have 2 queries in total.
There is no need to invent performance problems that do not exist.
Update or Insert return only count of affected rows. Commands Select, Insert, Update performed separately. This is a SQL issue, not Laravel.
For single inserts (if you want add one row) you can use insertGetId method of a model.
For example,
$id = User::insertGetId([
'email' => 'john#example.com',
'name' => 'john'
]);
But you get only ID of record. You need to run select to get full data of the row.
To save multiple records with one query you can use
DB::table('table_name')->insert($data);
Since this won't be an eloquent method, you should pass all the columns including created_at and updated_at.
I don't know what is the method name for update.

Laravel Lighthouse: how to delete records that match certain conditions (rather than deleting via primary key)

In Laravel Lighthouse GraphQL, I'd love to be able to delete records that match certain conditions rather than passing just an individual ID.
I get this error:
The #delete directive requires the field deletePostTag to only contain a single argument.
This functionality seems currently unsupported, but if I'm wrong and this is actually supported, please let me know, because this would be the most straightforward approach.
So then my second approach was to try to first run an #find query to retrieve the ID of the record that I want to delete (based on certain fields equaling certain values).
But https://lighthouse-php.com/4.16/api-reference/directives.html#find shows:
type Query {
userById(id: ID! #eq): User #find
}
and does not show how I could provide (instead of the primary key ID) 2 arguments: a foreign key ID, and a string.
How can I most simply accomplish my goal of deleting records that match certain conditions (rather than deleting via primary key)?
I'm not sure about the #delete functionality regarding multiple arguments, but from what you've posted that appears to be unsupported at the moment. Regarding your query, you should instead use something like #all in conjunction with #where which would allow you to filter the collection by as many vars/args as you'd like. If your argument list grows beyond 3 or so, I would take a look at Complex Where Conditions. They have worked very well for my team so far, and allow a lot of filtering flexibility.
Also take a look at the directive's docs stating:
You can also delete multiple models at once. Define a field that takes a list of IDs and returns a collection of the deleted models.
So if you return multiple models you'd like to delete from your query, you may use this approach to delete them all at once.

Laravel,end of migrations relationship at some time

hi I have the following question. In laravel I created 2 tables, apartments and sponsors with many to many relationships. Depending on the plan chosen, the sponsors have a variable duration that I valued in the pivot table(start_time and end_time). I would need the relationship between the apartment and the sponsor to end automatically after the sponsorship period has ended(when the date and day coincide with the end_time of the pivot table). How could I do such a thing? I thought about using detach but I'm not sure how.
It is always a good idea to look at these problems from different perspectives. Like the two comments mention, you could use Job Scheduling In windows or cron jobs in linux systems.
The next option is to create another field in your pivot which is something like “active”. So this will be a boolean and will always return a true or false. Now you can combine task scheduling and using a custom artisan command, you can keep checking if the sponsor expired and if it did expire, set the active field to false.
And to top it all, when you get your data, simply filter your query. I do not know how your code looks like but here is a sample code of a pivot and how I would have filtered it (not tested):
//Here active null assumes it is false value. Active 1 assumes it is true. So the active field will be nullable
$myQuery = Sponsor::with([‘apartments’ => function($q) {
$q->where(‘active’, null)->get();
}])->get();
//The apartments is assumed to be the pivot relationship in your sponspor model
This is just a simple example of how you could chain and query a relationship, whether be a pivot or any other table, you can do custom queries within like mentioned above. Something along the lines should work in your case

Laravel Validation: Get count of existing rows to prevent deletion if last row

During the Validation step, I need to prevent the user from deleting last row in a pivot table. Put another way, a user must always have at least one entry in the pivot table.
So when a user requests to $user->pivot->detach($ids) I want to somehow check the row count in the pivot table for the user and throw a validation error if the count is 1 or less.
I know I can extend Validator and make a custom rule, but hoping someone knows a built-in way, or has a custom method written already.
Note: the exists:pivot_user validation method returns boolean, so it won't work.

Laravel model event to restrict query

Is there a way in L4 to use model events to restrict all queries run using that model.
i.e. An event that fires before the query that allows me to modify the query.
Under certain circumstances I want to further restrict the records that are returned from all queries against a particular table/model.
e.g. A user of type customer should only see orders relating to them, so would like to restrict all Order::get(), Order::first() etc. by adding Order::where('customerid', '=', '').
It would be good if it's possible to set this up on the model so I don't have to consider it each time I run a query - I can run it knowing that these basic conditions will be applied automatically where needed.

Resources