Reputation: 46
here i am getting data from 3 models banner , banner types and its positions (there is no issue with banner type model so i am skipping it )[the admin template is generated from quickadminpanel ]
my data structure looks like
banner
Schema::create('banners', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('banner_name')->unique();
$table->string('banner_header');
$table->string('banner_caption')->nullable();
$table->string('banner_btn_txt');
$table->string('banner_btn_link');
$table->string('banner_btn_color');
$table->timestamps();
$table->softDeletes();
});
2021_01_15_000003_create_positions_table.php
Schema::create('positions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('position');
$table->timestamps();
});
2021_01_15_000019_add_relationship_fields_to_positions_table.php
Schema::table('positions', function (Blueprint $table) {
$table->unsignedBigInteger('banner_id')->nullable();
$table->foreign('banner_id', 'banner_fk_2983258')->references('id')->on('banners');
});
$banner = Banner::get();
$banner_types = BannerType::get();
$positions = Position::with(['banner'])->orderBy("position")->get();
$banner_array = array();
$banner_no_position = array();
foreach ($banner as $banner){
if(Position::where('banner_id',$banner->id)->count() != 0){
$banner_array = array($banner);
}else{
// print_r($banner);
$banner_no_position = array($banner);
}
}
what i am trying to do is separating the banners which has positioned and which has not positioned by creating 2 different arrays
the one called $banner_array
is working smoothly but the other $banner_no_position
is just showing the last object and discarding the other objects
for example i have created 4 banners and i have positioned just 2 then i get 2 objects in $banner_array
and only 1 object in $banner_no_position
array but it should have 2 or more array since i have not positioned 2 banners
my blade looks like the https://pastebin.com/hwAqjZ7S and my complete controller looks like https://pastebin.com/LvvLPSNP its bit messy but i will beautify few functions later The functions i am using from controllers are index and newPosition to read and to save data resp
banner model looks like https://pastebin.com/75nCdBvh and position model looks like https://pastebin.com/vr7GPd8A
Upvotes: 0
Views: 218
Reputation: 50491
If you have a relationship setup you can use the relationship to help with this:
$banners = Banner::has('positions')->get();
$banners_without_positions = Banner::doesntHave('positions')->get();
Here we are using a query to return all Banners that have any Positions. Then we are doing another query to return all Banners that do not have any Positions.
Or you could use the withCount
method to get a count of the relationship for every Banner then use the collection's partition
method to break this into 2 different groups:
[$banners, $banners_without] = Banner::withCount('positions')
->get()
->partition(fn ($i) => $i->positions_count);
Here we are saying if the count of this relationship is a positive number (true) then sort it into the first set, if not (no positions) sort it into the second set. You can also do this by just eager loading positions
(with('positions')
) then doing a count on the relationship, $i->positions->count()
but if you don't need the relationship loaded there is no need to load it and hydrate the models.
Adjust the naming of things as needed.
Laravel 8.x Docs - Eloquent - Relationships - Querying Relationship Existence has
Laravel 8.x Docs - Eloquent - Relationships - Querying Relationship Absence doesntHave
Laravel 8.x Docs - Eloquent - Relationships - Counting Related Models withCount
Laravel 8.x Docs - Collections - Available Methods partition
Upvotes: 1