I tried to query Item model & group by groupId, then further group the group by user_id & sum the sales_count but got an error. Below is my code.
$items = Item::where('sold', true)->get()->groupBy('groupId', function ($query){
$query->select(DB::raw('userid,sum(sales_count) as total_sales_count'))->groupBy('userid');
})->get();
I got the error below:
Too few arguments to function Illuminate\Support\Collection::get(), 0 passed in
Expected result (Eloquent\Collection):
[
17558 => [
[
"userid" => "2"
"total_sales_count" => "3"
],
[
"userid" => "4"
"total_sales_count" => "1"
],
],
18647 => [
[
"userid" => "5"
"total_sales_count" => "6"
],
[
"userid" => "7"
"total_sales_count" => "4"
],
]
]
Model Structure:
Schema::create('items', function (Blueprint $table) {
$table->id();
$table->integer('userid');
$table->integer('sales_count')->default(1);
$table->string('groupId')->nullable();
$table->boolean('sold')->default(true);
$table->timestamps();
});
Your query should be like this -
$item = Item::where('sold', true)
->select('user_id', DB::raw('sum(items.sales_count) as total_sales_count'))
->groupBy('groupId')
->get();
Related
I trying to return access the attributes inside a array of object and it is giving this error Exception: Property [id] does not exist on this collection instance.
Here is what I have tried:
protected function formatted($classroom)
{
return [
'courses' => [
'id' => $classroom->courses->id,
'name' => $classroom->courses->name,
'slug' => $classroom->courses->slug,
'coursteachers' => [
'id' => '$classroom->courses->coursteachers->id',
'email' => '$classroom->courses->coursteachers->email',
'uid' => '$classroom->courses->coursteachers->uid',
]
],
];
}
And here is the actual data:
"courses": [
{
"id": 1,
"name": "Analytics",
"slug": "analytics",
"status_id": 1,
"deleted_at": null,
"pivot": {
"classroom_id": 2,
"courses_id": 1
},
"coursteachers": [
{
"id": 3,
"uid": "S0120-46890",
"email": "teacher#vschool.com",
"user_type": "Teacher",
}]
}]
You need to iterate through courses and also courseteachers since they both represent an array but rather an object
protected function formatted($classroom)
{
$result = [];
foreach($classroom->courses as $course) {
$result[] = [
'courses' => [
'id' => $classroom->courses->id,
'name' => $classroom->courses->name,
'slug' => $classroom->courses->slug,
'coursteachers' => $this->getCourseTeachers($cours)
],
];
}
return $result;
}
private function getClassroomTeachers($classroom) {
$result = [];
foreach($classroom->courses as $cours)
{
foreach ($cours->coursteachers as $key => $teacher) {
$result[] = [
// 'coursteachers'=> [
'id' => $teacher->id,
'email' => $teacher->email,
'uid' => $teacher->uid,
'last_name' => $teacher->profile->last_name,
'first_name' => $teacher->profile->first_name,
'middle_name' => $teacher->profile->middle_name,
// ],
];
}
}
return $result;
}
Since courses is an array, you should pick an object using the proper index.
Foe example: try $classroom->courses[0]->id instead of $classroom->courses->id. Here, '0' is the index.
Also it is better if you check if the index exists before you do it. For an example.
'id' : isset($classroom->courses[$index]) ? $classroom->courses[$index]->id : ''
Edit:
In case of a Eloquent collection you should use $classroom->courses->get($index)->id instead of array like retrieval.
[
"bob" => $books
"maria" => $otherBooks
]
to
[
[
name => "bob"
data => $books
],
[
name => "maria"
data => $otherBooks
]
]
You can utilize map, map takes $item and $key there is your input arrays key value, as the argument for the closure. If you map those to expected array structure this should work.
$result = collect([
'bob' => $books
'maria' => $otherBooks
])->map(function ($item, $key) {
return [
'name' => $key,
'data' => $item,
]
});
You can do this easily with collections.
collect([
"bob" => $books
"maria" => $otherBooks
])->map(function ($books, $name) {
return [
'name' => $name,
'data' => $books
];
});
When I call my image resource it returns the correct data from my model:
Image resource:
return [
'id' => $this->id,
'name' => $this->name,
'presentation' => $this->presentation->description,
'slug' =>$this->filename
];
Image Model:
public function presentation()
{
return $this->hasOne(ProductPresentation::class, 'id', 'presentation_id');
}
Returns:
{
"data": [
{
"id": 1,
"name": "White Gold",
"presentation": "Product x",
"slug": "products/white-gold.jpg"
}
}
But when I call the manyToMany (Products -> images) relation I only get the the Id not the foreign relation
"data": [
{
"id": 1,
"name": "White Gold",
"price": "€ 10,00",
"images": [
{
"id": 1,
"name": "White Gold",
"filename": "products/white-gold.jpg",
"presentation_id": 1
}
]
},
The Products resource calls the image resource but this doesn't load the relation ( need "presentation": "Product x" instead of "presentation_id": 1)
Using resource:
return [
'id' => $this->id,
'name' => $this->name,
'price' => $this->formattedPrice,
'images' => $this->images
];
using model:
public function images()
{
return $this->belongsToMany(Image::class);
}
So the question would be how do I add the relation to belongsToMany(Image::class)
Try to change
return [
'id' => $this->id,
'name' => $this->name,
'price' => $this->formattedPrice,
'images' => $this->images
];
To
return [
'id' => $this->id,
'name' => $this->name,
'price' => $this->formattedPrice,
'images' => YourImageResource::collection($this->images)
];
I want to link multiple images to multiple albums. I got the following error:
SQLSTATE[HY000]: General error: 1364 Field 'album_id' doesn't have a default value
I don't want to have a default value for my album_id.
My fotos table:
public function up()
{
Schema::create('fotos', function (Blueprint $table) {
$table->increments('id');
$table->string('foto');
$table->timestamps();
$table->integer('album_id');
});
}
My album table:
public function up()
{
Schema::create('albums', function (Blueprint $table) {
$table->increments('id');
$table->string('foto');
$table->string('naam');
$table->timestamps();
});
}
My pivot table:
public function up()
{
Schema::create('album_foto', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('album_id');
$table->integer('foto_id');
});
}
My albums table seeder:
<?php
use Illuminate\Database\Seeder;
use App\Album;
class AlbumsTableSeeder extends Seeder {
First album
public function run() {
$album = new Album([
'foto' => 'Vlinder.jpg',
'naam' => 'Black & White'
]);
$album->save();
Second album
$album = new Album([
'foto' => 'Waterval2.jpg',
'naam' => 'Mother Nature'
]);
$album->save();
}
}
My fotos table seeder:
<?php
use Illuminate\Database\Seeder;
use App\Foto;
class FotosTableSeeder extends Seeder {
Images first album
public function run() {
$foto = new Foto([
'foto' => 'Vlinder.jpg'
],
[
'foto' => 'Berlijn.jpg'
],
[
'foto' => 'Mist.jpg'
],
[
'foto' => 'Mystery_Guy.JPG'
],
[
'foto' => 'Pop.JPG'
],
[
'foto' => 'Pop2.JPG'
],
[
'foto' => 'Pop3.JPG'
],
[
'foto' => 'Spiegel.JPG'
],
[
'foto' => 'Stammen.jpg'
],
[
'foto' => 'Voet.jpg'
],
[
'foto' => 'Vogels.jpg'
]
);
$foto->save();
Images second album
$foto = new Foto([
'foto' => 'Maan.jpg'
],
[
'foto' => 'Plant.JPG'
],
[
'foto' => 'Sneeuw.JPG'
],
[
'foto' => 'Stammen.jpg'
],
[
'foto' => 'Steen.JPG'
],
[
'foto' => 'Vlinder.jpg'
],
[
'foto' => 'Vogels.jpg'
]
);
$foto->save();
}
}
Use unsigned column definition for bind foreign keys to ids.
Define also foreign keys to connect your tables properly.
Try to declare your table in this way:
<?php
// Fotos table
public function up() {
Schema::create('fotos', function (Blueprint $table) {
$table->increments('id');
$table->string('foto');
$table->integer('album_id')->nullable()->unsigned();
$table->timestamps();
$table->foreign('album_id')->references('id')->on('albums');
});
}
// Album table
public function up() {
Schema::create('albums', function (Blueprint $table) {
$table->increments('id');
$table->string('foto');
$table->string('naam');
$table->timestamps();
});
}
// Pivot table
public function up() {
Schema::create('album_foto', function (Blueprint $table) {
$table->increments('id');
$table->integer('album_id')->unsigned();
$table->integer('foto_id')->unsigned();
$table->timestamps();
$table->foreign('album_id')->references('id')->on('albums');
$table->foreign('foto_id')->references('id')->on('fotos');
});
}
I have 2 models that are many to many related.
Workshop
public $belongsToMany = [
'registrations' => [
'Wooltown\Events\Models\Registration',
'table' => 'wooltown_events_registration_workshop',
'count' => true,
],
];
Registration
public $belongsToMany = [
'workshops' => [
'Wooltown\Events\Models\Workshop',
'table' => 'wooltown_events_registration_workshop',
'count' => true,
],
];
I'm fetching a record like this:
$vars['registration'] = Registration::with('workshops')->find($registration->id);
I'm expecting an array of all associated workshops (in this case 2) in the result but the workshops array only shows me this:
...
"workshops": [{
"registration_id": 113,
"count": 2,
"pivot": {
"registration_id": 113
}
}]
...
What am I missing here? How do I get a collection of the associated workshop models?
You should use the counter as a separate relation:
public $belongsToMany = [
'workshops' => [
'Wooltown\Events\Models\Workshop',
'table' => 'wooltown_events_registration_workshop',
],
'workshops_count' => [
'Wooltown\Events\Models\Workshop',
'table' => 'wooltown_events_registration_workshop',
'count' => true,
],
];