In the current application, there is a model Part and a model Supplier. Every Part has a Supplier.
public function supplier()
{
return $this->belongsTo(Supplier::class);
}
I added an accessor to get the name of the supplier.
If i return the whole dataset, i get the supplier:
public function getSupplierNameAttribute()
{
return $this->supplier;
}
"supplierName": {
"id": 1,
"uuid": "37e3a715-09d3-4fac-ae88-8f12e63fe79c",
"name": "Laserteam",
"street": "8602 Dessie Tunnel",
"zip": "15869",
"city": "New Clementview",
"email_send_type": null,
"active": 0,
"created_at": "2020-01-09 09:46:02",
"updated_at": "2020-01-09 09:46:02",
"deleted_at": null,
"action": "",
"activeLabel": "<span class='badge badge-secondary'>Inaktiv<\/span>"
},
If i try to get only the name (what I need finally), there is an error:
public function getSupplierNameAttribute()
{
return $this->supplier->name;
}
ErrorException: Trying to get property 'name' of non-object in file /gopanel/sites/7industry_net/public/7time/app/Models/Part/PartAttribute.php on line 48
If i try in this way, it works:
public function getSupplierNameAttribute()
{
return $this->supplier['name'];
}
Why does return $this->supplier->name; not work?
It's hard to say what could be the problem here, but:
Make sure you don't have supplier in casts for your model
Make sure you don't use supplier for database column name or you don't make somewhere something this
$this->supplier = $this->supplier->toArray();
It seems supplier property somewhere becomes array that's why one notation works but the other doesn't.
I’m not really sure what’s going on there; if you have a supplier relation then accessing the property should lazy-load the relationship.
Alternatively, you could try this syntax:
public function getSupplierNameAttribute()
{
$this->loadMissing('supplier');
return $this->getRelation('supplier')->name;
}
However, I’d avoid defining accessors like this. It can lead to N+1 problems if you say, retrieve a collection of parts and then call $part->supplier_name on each one without eager-loading the supplier relationship.
Personally, if I’m accessing attributing on relations that I prefer to do it through the relation (i.e. $part->supplier->name) so any relations I need to eager load are shown to me.
Try this code
public function getSupplierNameAttribute()
{
return $this->supplier->name ?? 'supplier not exists';
}
Related
I'm having trouble retrieving data through relationships.
My database structure (simplified):
orders:
id
user_id
product_id
order_items:
order_id
product_id
I need to get using relationships, all orders along with the items in the array.
Order model:
public function items()
{
return $this->hasMany(OrderItem::class, 'order_id', 'id');
}
Test controller:
public function test()
{
return Order::with('items')->get();
}
Result I got when accessing test():
[
{
"id": "d7baaae9-b925-4ff0-8bba-13e8e88d429b",
"user_id": "fa2a5f73-379d-4ab7-9bc5-81cdbd47f3b0",
"subtotal": "0.00",
"discount": "0.00",
"coupon_code": "0",
"total": "0.00",
"paid": false,
"refunded": false,
"created_at": "2022-07-26T16:41:50.000000Z",
"updated_at": "2022-07-26T17:51:45.000000Z",
"items": [
]
}
]
The "items" array does not exist in the orders table, it is coming through the relationship, but it comes empty. There is a record in the database relating orders with order_items, the OrderItem model is correctly accessing the database when I test. I don't know what the problem could be.
[EDIT_01]: I just found out that the problem is in the id I'm using, I'm using type Uuid (Ramsey\Uuid\Uuid\Uuid::uuid4()) for the keys of my tables, somehow it's not working, but when I testo with conventional ID works. Help-me.
I have the same issue, my fix is I add
protected $keyType = 'string';
to the table which has string id (uuid). Hope it can help
hope you found a solution, if not testing out your code sample here, and everything works fine for me,
public function items()
{
return $this->hasMany(OrderItem::class);
}
use this instead, should give you a better result
Try removing the third parameter and just use this:
return $this->hasMany(OrderItem::class, 'order_id');
This should work given your Database setup example, make sure you actually have items in your database that belong to that order you are debugging as well.
Sorry for my bad english, I want to get a single row in my object. And I want that in random order. Im using array_rand() and it only return errors as stated below:
ErrorException: array_rand() expects parameter 1 to be array, object given in file C:\xampp\htdocs\user\TestProject\app\Http\Controllers\TestController.php on line
Here is my object.
"my_list": [
{
"id": 1,
"name": "My Name Test",
"address": [
{
"id": 1,
"city": "Manila",
"country": "Philippines"
}
]
},
{
"id": 2,
"name": "Your Name Test",
"address": [
{
"id": 2,
"city": "Cebu",
"country": "Philippines",
}
]
}
]
The problem is I want only to get a single row to the my_list which is object and not an array.
Here is my code.
$course = Course::where('id', 1)->with('my_list')->first();
$random_list = array_rand($course->my_list);
return $random_list;
I also try adding number of row in the array_rand like this.
$random_list = array_rand($course->my_list, 1);
But still not working.
What did I missed?
Any Eloquent query returns, by default, a Collection, even for the underlying relationships. Since you are working with one, this should work:
$course->my_list->random();
This will return only one item. If you want more, you could pass an argument to the random() method specifying the count of items you want.
For more information, check the documentation.
This Object is a Laravel collection. Please refer to the collection documentation.
https://laravel.com/docs/5.7/collections#method-random
You can try $course->my_list->random()
If you still wanna do this with your approach, can you try get_object_vars function to cast object into array.
$array = get_object_vars($object);
so that you can use them as an array in array_rand.
You might get an error, hence that it's an multi-dimensional array. Let me know so i may update.
Update for multidimensional:
Please refer to this.
// The second parameter of json_decode forces parsing into an associative array
$array = json_decode(json_encode($object), true);
try this:
$course = Course::where('id', 1)
->with(['my_list' => function($query) {
$query->inRandomOrder();
}])->first();
return $course->my_list;
Try this method:
$course = Course::where('id', 1)
->with(['my_list' => function($query) {
$query->inRandomOrder()->first();
}])->first();
return $course->my_list;
this method is more efficient since you will only get 1 row from my_list not like when you use $course->my_list->random() which retrieves all data and from there select a random row.
$random_list = $course['my_list']->random(number);
ps: number = number of element you want to get ,
I'm having the following problem, I'm using scope in Laravel and I have the following relationship:
Enquiry
pickup_address
dropoff_address
Notes
This is referenced in the model:
public function pickup_address() {
return $this->belongsTo('App\Address', 'pickup_address', 'id');
}
I want to return the enquiry, as well as postcode which is stored in the Address table. I just want this column from this table and I have done the following:
return $query->with(['pickup_address' => function ($query) {
$query->select('postcode');
}])->get();
This gives the following (json):
{
"id":1,
"pickup_address":null
"notes":"hello world",
"created_at":"2017-06-08 09:56:52",
"updated_at":"2017-06-08 09:56:52"
}
This is not giving the postcode and just gives the pickup_address as null. However, removing the $query->select('postcode') gives:
{
"id":1,
"pickup_address": {
"id":140,
"house_number":null,
"address_1":"Address 1",
"address_2":null,
"postcode":"POSTCODE",
"city":"CITY",
"county":"C0UNTY",
"created_at":"2017-06-08 09:56:23",
"updated_at":"2017-06 0}",
"notes":"Hello world","
"created_at":"2017-06-08 09:56:52",
"updated_at":"2017-06-08 09:56:52"
}
However, I'm using Vue and using a table, so I just need the particular field to be returned that matches the column, rather than the entire object being returned.
Can anyone suggest a solution, please? I have followed some examples online and they suggest the $query->select('postcode')
how can i merge laravel relationship results in to one object?
MyController.php
public function getUser($id) {
return TournamentUser::where('customer_id','=', $id)->with('user')->get();
}
MyModel.php
public function user() {
return $this->hasOne('App\Models\Customer','customer_id', 'customer_id');
}
returning result :
[{
"id":1,
"tournament_id":3,
"customer_id":2016827550,
"point":0,
"user":{
"id":1,
"customer_id":2016827550,
"nickname":"OMahoooo"
}
}]
as expected query returns user section as array but i expect result like this :
[{
"id":1,
"tournament_id":3,
"customer_id":2016827550,
"point":0,
"nickname":"OMahoooo"
}]
only get nickname section without user array. I hope you understand me.
Sorry for my english , have a nice day
You can load the data and remap it manually using map() method. I've just tested this code and it works perfectly with hasOne() relationship:
$users = TournamentUser::where('customer_id', $id)->with('user')->get();
$users->map(function ($i) {
$i->nickname = $i->user->nickname; // Set related nickname.
unset($i->user); // Delete user data from the collection.
return $i;
});
Alternatively, you could use an accessor, but in this case, you'll meet the N+1 problem.
for some weird reason building this model with Eloquent is hiding the Pivot that I am requiring explicitly in the relation (This Model is called Match):
public function scorers()
{
return $this->belongsToMany(
Player::class,
'match_players',
'match_id'
)->withPivot(
'goals'
)->where(
'goals', '>', 0
);
}
public function scopeComplete($query)
{
return $query->with(
'homeTeam',
'awayTeam',
'scorers'
);
}
The problem is the json result of scorers is as follows
"scorers": [
{
"id": 196,
"name": "Tino",
"surname": "Heck",
"age": 24
},...
And is hiding the pivot (goals) team_id and goals which should appear on each object inside a nested object called pivot, did anyone came across some problem like this? I cat find anything around here. Something like
"scorers": [
{
"id": 196,
"name": "Tino",
"surname": "Heck",
"age": 24,
"pivot": {
"goals": 3
}
},...
Db structure is
Match
- id
- ..
Players
- id
- ...
MatchPlayer
- player_id
- match_id
- goals
The result inside scorers is correct, so I get the actual player where goals > 0, but not the pivot I am looking for
Thanks in advance.
Silly me, I found the error, the problem was that Iwas hiding pivots on Player Model :(
So the lesson here is the $hidden array property that counts is the one on the relation model rather than the one on the Parent (Match in this case)