Octobercms: Many to many relations not showing - laravel

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,
],
];

Related

Best way to update a lot of data with difference value?

I have a lot of data and each record have difference value. I try to loop insert/update data but it take time. Is it have better way to improve my code?
I don't want to delete all data before update.
$data = [
[ 'id' => 1, 'name' => 'A' ],
[ 'id' => 2, 'name' => 'B' ],
[ 'id' => 3, 'name' => 'C' ],
[ 'id' => 4, 'name' => 'D' ],
.
.
.
[ 'id' => 10000, 'name' => 'ZYX' ],
]
foreach ($data as $item) {
DB::table('my_table')->updateOrInsert(['id' => $item->id], $item);
}
Thank.
You can use upsert in Laravel 8.x or use this package: https://github.com/staudenmeir/laravel-upsert to use INSERT ON DUPLICATE
$data = [
[ 'id' => 1, 'name' => 'A' ],
[ 'id' => 2, 'name' => 'B' ],
[ 'id' => 3, 'name' => 'C' ],
[ 'id' => 4, 'name' => 'D' ],
.
.
.
[ 'id' => 10000, 'name' => 'ZYX' ],
];
DB::table('my_table')->upsert($data, 'id');
use laravel upsert method here
for example you want to update if exists or insert record if not exists
$data = [
[
'id' => 1
'name' => 'J.K. Rowling',
'author' => 'Harry Potter',
'quantity' => 15
],
[
'id' => 2
'name' => 'Cal Newport',
'author' => 'Deep Work',
'quantity' => 20
]
];
DB::table('books')->upsert($data, ['id'], ['quantity']);
1.The first argument consists of the values to insert or update.
2.The second argument lists the column(s) that uniquely identify records (id in our case) within the associated table.
3.The third and final argument is an array of columns that should be updated if a matching record already exists in the database. We want the quantity to be updated in our case.
for more detail read official docs upsert

Laravel: How to access Object inside an array

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.

Laravel 5.8 ManyToMany relationship child relation usign foreign key doesn't work

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)
];

Convertion of Elasticsearch Query from 2.0 to 5.0

Guys I am newbie in elastic search and trying to migrate from 2.* to 5.*.
I have a query which I cannot convert. I tried searching google, as well as read documentation but examples in it are very basic and don't really help in here. Maybe someone can help me to convert the following query into modern one? I am using php client for it.
$query = [
'index' => 'index_name',
'type' => 'table',
'body' => [
'query' => [
'filtered' => [
'query' => [
'bool' => [
'must' => [
[
'match' => [
'_all' => [
'query' => 'zonda',
'fuzziness' => 1,
],
],
],
],
],
],
'filter' => [
[
'term' => [
'foo' => 1,
],
],
],
],
],
],
'size' => 10000,
];
Not much into php, so could not check it, but it should be something like this:
$query = [
'index' => 'index_name',
'type' => 'table',
'body' => [
'query' => [
'bool' => [
'must' => [
[
'match' => [
'_all' => [
'query' => 'zonda',
'fuzziness' => 1,
],
],
],
],
'filter' => [
[
'term' => [
'foo' => 1,
],
],
],
],
],
],
'size' => 10000,
];
The filtered query is now gone, and you can use the filter part of the bool query.

Why won't CakePHP 3.2 Paginator sort on my query results?

CakePHP query and such from the controller:
$ratings = $this->Ratings->find('all')->group('manufacturer');
$ratings->select(['manufacturer',
'count' => $ratings->func()->count('*'),
'max' => $ratings->func()->max('psi_score'),
'min' => $ratings->func()->min('psi_score')]);
$ratings = $this->paginate($ratings);
$this->set(compact('ratings'));
$this->set('_serialize', ['ratings']);
Here is what debug($ratings) produces:
'items' => [
(int) 0 => object(Cake\ORM\Entity) {
'manufacturer' => 'A10Green Technology',
'count' => (int) 8,
'max' => '7.41',
'min' => '6.57',
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Ratings'
},
In the view, sorting on manufacturer works fine. That is an original db field. The count, max and min values are not getting sorted.
Here are the sort calls for the view:
<th><?= $this->Paginator->sort('manufacturer')?></th>
<th><?= $this->Paginator->sort('count')?></th>
<th><?= $this->Paginator->sort('max')?></th>
<th><?= $this->Paginator->sort('max')?></th>
You need to whitelist the fields that you want to allow to be sorted like in: Pagination
public $paginate = [
'sortWhitelist' => [
'id', 'title', 'Users.username', 'created'
]
];
Otherwise by default cake 3 blocks it

Resources