Laravel array instead of collection - php

In my Laravel application, I have this model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Division extends Model
{
protected $fillable = [
'name','company_id', 'location_id'
];
protected $casts = [
'name' => 'string',
'company_id' => 'integer',
'location_id' => 'integer'
];
public function company()
{
return $this->belongsTo(Company::class);
}
public function location()
{
return $this->belongsTo(Location::class);
}
}
$division->company returns a collection
$division->location returns an array
Why this two relations has different results? (Sorry for bad formating....)

As you've just shown in the comments (and then edited), you're using it with get(). That's why you're getting a collection and not an object.
$division->company returns an object. Then you're running another query with $division->company->anotherRelationship()->get() which returns a collection of related objects.

Related

How to display a complex relationship field for Laravel Backpack?

I have a relationship
Candidate -> Vacancy -> User
Candidate:
class Candidate extends Model
{
public function vacancy()
{
return $this->belongsToMany(
Vacancy::class,
'vacancy_has_candidate',
'candidate_id',
'vacancy_id'
);
}
}
Vacancy:
class Vacancy extends Model
{
public function candidate()
{
return $this->belongsToMany(
Candidate::class,
'vacancy_has_candidate',
'vacancy_id',
'candidate_id'
);
}
public function manager() {
return $this->hasMany(User::class, 'manager_id');
}
}
User:
class User extends Authenticatable
{
public function vacancy()
{
return $this->belongsTo(Vacancy::class, 'manager_id');
}
}
I want to display in СRUD candidates the field of the relationship in which I call the manager method with the output of the field from the User model.
for example
class CandidateCrudController extends CrudController
{
....
public function setupCreateOperation()
{
$this->crud->addFields([
[
'name' => 'vacancy',
'type' => 'relationship',
'label' => 'Vacancy',
'model' => Vacancy::class,
'entity' => 'manager', <- this method in Vacancy model
'attribute' => 'title', <- this column name in User
'ajax' => true,
]
]);
...
I get an error
"Looks like field vacancy is not properly defined. The manager() relationship doesn't seem to exist on the App\Models\Candidate model"
I can’t understand why the backpack is looking for a manager method in Candidates, although in the model I indicated a Vacancy in which this relationship method exists. And how to do it right?
KorDEM.
You will not be able to achieve that as per Backpack Documentation:
entity is the method that defines the relationship on the current model, in your case App\Models\Candidate is the CrudController model. So entity there should be the vacancy relation.
If you are using Backpack\PRO paid addon you should be able to list the vacancies with the desired information by using something like:
$this->crud->addField([
'name' => 'vacancy',
'subfields' => [
['name' => 'manager']
]
]);
If you need aditional pivot fields you need to provide ->withPivot in the relation.
Check BelongsToMany documentation on Backpack website

BadMethodCallException Call to undefined method App\Models\User::role()

I code a attendance employee system to load reports of time employers
i got below error
What should I do to solve this problem?
BadMethodCallException
Call to undefined method App\Models\User::role()
Did you mean App\Models\User::only() ?
my user.php model:
class User extends Authenticatable
{
use HasApiTokens;
use HasFactory;
use Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
protected $appends = [
'profile_photo_url',
];
}
Report Controller
$employees = User::whereHas('role', function ($query) {
$query->where('employee');
})
->get();
$dateRange = $reportService->generateDateRange();
$timeEntries = $reportService->generateReport($request->input('employee'));
if ($timeEntries) {
$chart = new LaravelChart([
'chart_title' => 'Hours of work per day',
'chart_type' => 'line',
'report_type' => 'group_by_date',
'model' => 'App\\TimeEntry',
'group_by_field' => 'time_start',
'group_by_period' => 'day',
'aggregate_function' => 'sum',
'aggregate_field' => 'total_time_chart',
'column_class' => 'col-md-8',
'continuous_time' => true,
]);
} else {
$chart = NULL;
}
as per the discussion, there is no roles table so you can't check using User::whereHas('role')
instead of that, you should use the following line
$employees = User::whereRole('employee')->get();
also, I have noticed that you haven't added role in fillable, you should add role to protected $fillable in order to consider that column for performing operations like create and save.
You must define a relation function role in your User model. Something like this:
public function role() {
return $this-><Type of relation>(Role::class);
}

How to get relation with a alias Model

Hello i have a model named Product and 2 model named ProductImage and ProductAttribute
What i wish ?
I want to access to the product attribute and get they element with this:
Product:with(['attribute','image','category']);
If i will access to the attribute laravel return me this error
Syntax error or access violation: 1066 Not unique table/alias: 'product_attributes'
in my Product Model
class Product extends Model
{
protected $fillable = [
'name',
'description',
'category_id',
];
protected $guarded = [
'id',
];
protected $dates = [
'created_at',
'updated_at',
];
public function category()
{
return $this->belongsTo(Category::class);
}
public function attribute()
{
return $this->belongsToMany(ProductAttributes::class,'product_attributes');
}
}
In my ProductAttribute Model
class ProductAttributes extends Model
{
protected $fillable = [
'attribute',
'value',
'price',
'product_id',
'stock'
];
public function product()
{
return $this->belongsTo(Product::class);
}
}
Comment: I'm using laravel as REST API

Laravel error: Property [name] does not exist on this collection instance

I'm trying to get a partner for each order using Laravel resource collections. But this throws up an error:
Property [name] does not exist on this collection instance
I get partners this way
Order_product.php
//...
class Order_product extends Model
{
protected $fillable = ['order_id', 'product_id', 'quantity', 'price'];
public function partner()
{
return $this->hasManyThrough(
'App\Partner', 'App\Order',
'partner_id', 'id', 'order_id');
//orders partners order_products
}
//...
Resources\Order_product.php
class Order_product extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'order_id' => $this->order_id,
'product_id' => $this->product_id,
'quantity' => $this->quantity,
'price' => $this->price,
'status' => $this->order->status,
'product_name' => $this->prod->name,
//return error
'partner_name' => $this->partner->name,
];
/*
//this method return:
//Invalid argument supplied for foreach() {"exception":"[object]...
$partners = [];
foreach($this->collection as $partner) {
array_push($partners, [
// 'partner_name' => $this->partner->name
]);
}
return $partners;
*/
}
}
Each order has one partner name. In the future, I will group them, but now I just need to output the partner_name
is relations when you use hasMany or hasManyThrough it returns you a collection, so you should use it in foreach or use with index
return [
'product_name' => $this->prod->first()->name, //first array in collection using first()
];
OR
return [
'product_name' => $this->prod[0]->name, //first array in collection using index
];
or you can write this code in foreach!
As you are using hasManyThrough or hasMany laravel relationship returns Illuminate\Database\Eloquent\Collection Instance.
If you want to get name you have to have one Model instance.
Solution 1: $this->parthner->first()->name
Solution 2: See this hasOneThough
public function partner(){
return $this->hasOneThrough(
'App\Partner', 'App\Order',
'partner_id', 'id', 'order_id');
}
Depens on your app logic
Hope this helps you

Return many object in my json response using resource

I'm kinda new to Laravel and I hope someone we'll be able to give me some help.
I apologize for my english
So I'm trying to develop an application with some friends to manage our food by sending alert when the peremption date is near.
I'm developing the API, the actual structure is this way:
A user,
A product,
A basket containing the user_id, the product_id and of course the peremption date.
So now when I make a call to get the User 'stock' on my API I wish I could get something like this:
{
'id' : 1,
'peremption_date': XX-XX-XX,
'product' : {
'id' : 3,
'name': bblablabala,
'brand' : blablabala
},
'id' : 2,
'peremption_date': XX-XX-XX,
'product' : {
'id' : 4,
'name': bblablabala,
'brand' : blablabala
},
}
So I took a look on resources and saw that if I define the right relations, this could do the stuff for my output.
I'll link you my actual class declarations and their resources:
User:
//user.php
class User extends Authenticatable
{
use Notifiable, HasApiTokens;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function baskets()
{
return $this->hasMany(Basket::class);
}
}
Product:
//Product.php
class Product extends Model
{
protected $table = 'products';
protected $fillable = ['code_barre', 'product_name', 'generic_name', 'brand', 'quantity'];
public function basket()
{
return $this->belongsToMany(Basket::class);
}
}
//productResource.php
class ProductResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'code_barre' => $this->code_barre,
'product_name' => $this->product_name,
'generic_name' => $this->generic_name,
'brand' => $this->brand,
'quantity' => $this->quantity,
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at,
];
}
}
Basket:
//Basket.php
class Basket extends Model
{
protected $table = 'baskets';
protected $fillable = ['user_id', 'product_id', 'dlc_date'];
public function user()
{
return $this->belongsTo(User::class);
}
public function product()
{
return $this->hasOne(Product::class);
}
}
//BasketResource.php
class BasketResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'dlc_date' => (string) $this->dlc_date,
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at,
'product' => $this->product
];
}
}
So when I try to store a new basket in my store method:
//BasketController.php
public function store(Request $request)
{
$this->product->storeProduct($request->input('code_barre'));
$att = DB::table('products')
->where('code_barre', '=', $request->input('code_barre'))
->first();
$basket = Basket::create([
'user_id' => $request->user()->id,
'product_id' => $att->id,
'dlc_date' => $request->input('dlc_date')
]);
return new BasketResource($basket);
}
I get the following error (this one)
saying than products.id_basket does not exist and its right, it's not supposed to exist. This is Basket who have a product_id. so I know this is coming from the relationship I declared but I can't figure how to do it right.
Can someone come and save me ???
Thanks a lot, I hope you understood me !
Wish you a good day
As I look at your Basket model, it seems you have to change your:
public function product()
{
return $this->hasOne(Product::class);
}
to:
public function product()
{
return $this->belongsTo(Product::class);
}
Because you have product_id in your baskets table. To use hasOne() relation, you will need to remove product_id from baskets table and add basket_id to products table, because hasOne() relation is something like hasMany(), only calling ->first() instead of ->get()

Categories