I am using Laravel 5.1.
I have two collections, $collectionA and $collectionB. Each collection contains Flashcards which extends Model. I am trying to do something like this, but it isn't working:
$collectionA->intersect($collectionB)
The reason is that while each Flashcard has the same id, their pivot tables are different. Ideally, I would like to ignore the pivot table and compare by ids only. Is there a way to do this?
Perhaps there's a more efficient way to do this, but you could reduce $collectionB to an array of its ids, then filter $collectionA to only those elements:
$bIds = $collectionB->lists('id')->toArray();
$intersected = $collectionA->filter(function($item) use ($bIds) {
return in_array($item->id, $bIds);
}
Related
I have three different models and I want to filter them and return them in the same object by creation date. The problem is that the filter must be applied on all models at once and not on each model successively.here are my three models, I don't know how to continue, need help
$quick = Model::with('user')->orderByDesc('id')->get();
$simple = Models::with('user')->orderByDesc('id')->get();
$suivi = Modelss::with(['user', 'position'])->orderByDesc('id')->get();
If there is no link in between the models and you want to retrieve data by ordering them all together. You need to use Collections for this.
What you can do after your 3 line of code is:
$quickSimpleMerged = $quick->merge($simple);
$merged = $quickSimpleMerged->merge($suivi);
$result = $merged->all();
Now that you have 1 collection including all data from 3 models of yours, you can simply run:
$result->sortByDesc('created_at');
Good day. I am building an API, in which I want to return some data. I have three tables
counsels
counsel_cases
analysis_sc
A section of the counsels table is shown below
A section of the counsel_cases is also shown below
Finally, a section of the analysic_sc is shown below.
I want that when a counsel is selected, through the counsel_id, I can fetch the cases belonging to the counsel from the counsel_cases, and then with that information, I want to be able to fetch the number of cases of such a counsel belonging to a legal head (area of practice) on the third table as shown in the design below.
How will that be possible. I have a relationship between counsel and counsel_cases though. Also, I have tried using a foreach loop as shown below, but I am unable to get the unique values of the legal_head.
public function getCounselPracticeAreas(Request $request)
{
$counsel_id = $request->route('counsel_id');
$cases = CounselCase::select('suit_number')->where('counsel_id', $counsel_id)->get();
$data = [];
foreach ($cases as $case) {
$values = AnalysisSc::select('legal_head')->where('suitno', $case->suit_number)->first();
array_push($data, $values);
}
return response()->json([
"message" => "successful",
"data" => $data
]);
}
However, this is the value I get
[![enter image description here][5]][5]
I want to get something like this:
$data : [
"legal_head" : [
"name" : "Criminal Law",
"count" : 2
]
]
Please, is this possible
I know this is quite long. And I hope I explained myself well. Thanks
you need to use SQL Joins to create a relationship between the tables and fetch the data
It looks like you're skipping using relationships in your models. Once you have your models set up, retrieving the data you need will be a lot easier with Laravel. You may want to separate your models/tables a little more and add relationships, like the following:
Models/tables:
Counsel (counsels)
id
name
LegalHead (legal_heads)
id
name
Case (cases)
id
suit_number
year
subject_matter
legal_head_id
case_counsels (This is not a model, just a relationship table)
id
case_id
counsel_id
appearing_for
role
Note: I wasn't sure how your data is structured. You can use this as start and adjust as necessary.
Relationships
The Many-Many relationship is suitable for the case counsels and you'll be able to add the role as a pivot(extra field) for the relationship.
https://laravel.com/docs/8.x/eloquent-relationships#many-to-many
Case
legal_head: belongsTo
counsels: belongsToMany with pivot for role
Counsel
cases: belongsToMany with pivot for role
Retrieving the Objects
When that is set up, you won't have to do as much query work. You can do this to get case data with counsels, legal_head and their role for each case:
$cases = Case::with('counsels','legal_head')->get();
And this to get the Legal Head names with the number of cases:
$legal_heads = LegalHead::withCount('cases')->get();
I have a N-N relationship between Films and Genres, and I am trying to get from a $film the objects in the table Genres that are NOT in $film->genres().
I have looked for trying to do something like Genres:all() - $film->genres() or to do a loop in order to erase everyone but there is no Collection method that allows me to do that.
How can I do that?
Thanks.
I finally found the solution:
$film = Film::findOrFail(1);
$hasGenres = $film->genres()->pluck('id');
$doesntHaveGenres = Genres::whereNotIn('id',$hasGenres)->get();
I am using Laravel 4.2.
If I want to duplicate a model I can use the following:
$newModel = $currentModel->replicate();
$newModel->save();
However I have this inside a loop, like so:
foreach ($this->models as $currentModel) {
$newModel = $currentModel->replicate();
$newModel->save();
}
Which obviously causes a several DB calls. I want something more efficient, so I can loop through my models and then outside of the loop use one DB call to write them all in one go.
In Laravel is there a way to replicate multiple models in one go?
You can use the insert statment of DB query builder like this :
foreach ($this->models as $currentModel) {
$newModel = $currentModel->replicate()
$newModels[] = $newModel->toArray();
}
DB::table('table_name')->insert($newModels);
No it not possible duplicate more than one model, you can see in the api documentation:
https://laravel.com/api/4.2/Illuminate/Database/Eloquent/Model.html#method_replicate
So if you would duplicate X models you need loop them and you can speific (with array parameter) wich columns you would like to not copy
This may be a dupe but I've been trawling for some time looking for a proper answer to this and haven't found one yet.
So essentially all I want to do is join two tables and attach a where condition to the entire collection based on a field from the joined table.
So lets say I have two tables:
users:
-id
-name
-email
-password
-etc
user_addresses:
-address_line1
-address_line2
-town
-city
-etc
For the sake of argument (realising this may not be the best example) - lets assume a user can have multiple address entries. Now, laravel/eloquent gives us a nice way of wrapping up conditions on a collection in the form of scopes, so we'll use one of them to define the filter.
So, if I want to get all the users with an address in smallville, I may create a scope and relationships as follows:
Users.php (model)
class users extends Eloquent{
public function addresses(){
return $this->belongsToMany('Address');
}
public function scopeSmallvilleResidents($query){
return $query->join('user_addresses', function($join) {
$join->on('user.id', '=', 'user_addresses.user_id');
})->where('user_addresses.town', '=', 'Smallville');
}
}
This works but its a bit ugly and it messes up my eloquent objects, since I no longer have a nice dynamic attribute containing users addresses, everything is just crammed into the user object.
I have tried various other things to get this to work, for example using a closure on the relationship looked promising:
//this just filters at the point of attaching the relationship so will display all users but only pull in the address where it matches
User::with(array('Addresses' => function($query){
$query->where('town', '=', 'Smallville');
}));
//This doesnt work at all
User::with('Addresses')->where('user_addresses.town', '=', 'Smallville');
So is there an 'Eloquent' way of applying where clauses to relationships in a way that filters the main collection and keeps my eloquent objects in tact? Or have I like so many others been spoiled by the elegant syntax of Eloquent to the point where I'm asking too much?
Note: I am aware that you can usually get round this by defining relationships in the other direction (e.g. accessing the address table first) but this is not always ideal and not what i am asking.
Thanks in advance for any help.
At this point, there is no means by which you can filter primary model based on a constraint in the related models.
That means, you can't get only Users who have user_address.town = 'Smallwille' in one swipe.
Personally I hope that this will get implemented soon because I can see a lot of people asking for it (including myself here).
The current workaround is messy, but it works:
$products = array();
$categories = Category::where('type', 'fruit')->get();
foreach($categories as $category)
{
$products = array_merge($products, $category->products);
}
return $products;
As stated in the question there is a way to filter the adresses first and then use eager loading to load the related users object. As so:
$addressFilter = Addresses::with('Users')->where('town', $keyword)->first();
$users= $addressFilter->users;
of course bind with belongsTo in the model.
///* And in case anyone reading wants to also use pre-filtered Users data you can pass a closure to the 'with'
$usersFilter = Addresses::with(array('Users' => function($query) use ($keyword){
$query->where('somefield', $keyword);
}))->where('town', $keyword)->first();
$myUsers = $usersFilter->users;