Groupby on relation laravel - php

Hey i have three table like this
--table plan--
id
name
....
----table letter---
id
plan_id
....
---table person----
id
plan_id
name
.....
Model i have :
---Model plan---
class plan extends Model
{
protected $table = 'plan';
public function letter(){
return $this->hasOne('App\letter');
}
public function person(){
return $this->hasMany('App\person');
}
}
--Model person--
class person extends Model
{
public function plan(){
return $this->belongsTo('App\plan');
}
}
--Model letter--
class letter extends Model
{
public function plan(){
return $this->belongsTo('App\plan');
}
}
And in controller i write code like this :
$letter = letter::find($id) // $id from url parameter and it's work
return view('letter',['letter' => $letter]);
Nah in view i wanna acces person name from letter model as distinct , so i write code like this
{{ #foreach ($letter->plan()->person()->groupBy('name')->get) as $person }}
but it return error like this :
Call to undefined method Illuminate\Database\Query\Builder::person()
Where is my mistake(s)?

There is a difference between $letter->plan() and $letter->plan. If you call it like a method, Laravel will return the Query Builder. If you call it like an attribute Laravel will return the model from that relation.
So you're trying to call your model on the Query Builder, which is a method that doesn't exists and creates the error. This will fix your problem:
$letter->plan->person()->groupBy('name')->get()
In your controller you can do:
$letter = letter::find($id) // $id from url parameter and it's work
$persons = $letter->plan->person()->groupBy('name')->get();
return view('letter', compact('letter', 'persons'));
And in your view:
#foreach($persons as $person)

Related

Laravel Eloquent appending a non-relation ship data with the result

I have this model file:-
namespace App;
use Illuminate\Database\Eloquent\Model;
class Observation extends Model
{
protected $fillable = ['observation', 'recommendation', 'priority', 'report_asset_id'];
protected $appends = ['facility'];
public function attachments()
{
return $this->hasMany('App\ObservationAttachment');
}
public function report_facility()
{
return $this->belongsTo('App\ReportFacility');
}
public function getFacilityAttribute()
{
return $this->report_facility()->facility;
}
}
And this is my query code:-
$observations = Observation::orderBy('created_at','desc')
->with('attachments')->get();
return response()->json($observations);
I am trying to append getFacilityAttribute to be included in result array .
I tried to use the protected $append model array but got error :-
Call to undefined method
Illuminate\Database\Eloquent\Relations\BelongsTo::facility()
The following line is incorrect:
return $this->report_facility()->facility
You are starting a query, calling the report_facility as a function (report_facility()), returns a query builder object, on which the facility function is unknown.
You should do:
return $this->report_facility->facility
In this case, eloquent will give you the ReportFacility model, from which you can retrieve the facility property or relation.
It's similar to:
return $this->report_facility()->first()->facility

Laravel relation with types

I have tried to find the best solution for my problem without getting exactly what i want.
I have 4 tables now, the structure looks like this.
:: Users ::
id
name
email
------
:: user_equipment ::
id
user_id
equipment_id
equipment_type
:: weapons ::
id
name
price
:: armor ::
id
name
price
My goal is to be able to use my relations like this:
$user->equipment
$user->equipment->weapons
$user->equipment->armor
Here is what i have right now:
User Model:
class User extends Model
{
public function equipment()
{
return $this->hasOne(UserEquipment::class);
}
}
UserEquipment Model:
class UserEquipment extends Model
{
public function weapons()
{
return $this->hasMany(Weapon::class);
}
}
First of all, your User model and UserEquipment model has the same class name.
Try this, change your user model to
public function weapons()
{
return $this->hasMany('App\Weapon', 'equipment_id')->where('equipment_type','weapon'); //second paramater tells what column to relate the id
}
public function armors()
{
return $this->hasMany('App\Armors', 'equipment_id')->where('equipment_type','armor');
}
Then here's how you query:
User::with('weapons', 'armors')->get();
This looks to me like a Many To Many Polymorphic Relationship.
In your case, you'll need to define your relationships this way:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Get all of the weapons owned by the user.
*/
public function weapons()
{
return $this->morphedByMany('App\Weapon', 'equipment', 'user_equipment');
}
/**
* Get all of the armors owned by the user.
*/
public function armors()
{
return $this->morphedByMany('App\Armor', 'equipment', 'user_equipment');
}
}
Doing your queries:
$user = App\User::find(1);
foreach ($user->weapons as $weapon) {
//
}
foreach ($user->armors as $armor) {
//
}
Try to change your tables like this:
:: Users ::
id
name
email
------
:: user_equipment ::
id
user_id
equipment_type
:: weapons ::
id
name
price
user_equipment_id
:: armor ::
id
name
price
user_equipment_id
Then you can use the functions as you were using them:
User Model:
class User extends Model
{
public function equipment()
{
return $this->hasOne(UserEquipment::class);
}
}
UserEquipment Model:
class UserEquipment extends Model
{
public function weapons()
{
return $this->hasMany(Weapon::class);
}
public function armor()
{
return $this->hasMany(Armor::class);
}
}
Notice in laravel Documentation that Laravel assumes in the Model Weapons there would be a foreign key call user_equipment_id:
https://laravel.com/docs/5.7/eloquent-relationships#one-to-many

Laravel 5.6 Reverse HasManyThrough

I have the following table structure in my database:
products
id
product_formats
id
product_id
product_prices
id
product_format_id
When I'm trying to do $this->format->product; inside my ProductPrice class, I get an error:
LogicException: App\ProductPrice::product must return a relationship instance.
When I perform a dd inside my function:
dd($this->format()->first()->product);
I get the instance of the product. However, removing the dd would still throw the exception.
Why am I getting the LogicException?
ProductPrice
class ProductPrice extends Model
{
public function format()
{
return $this->belongsTo(ProductFormat::class, 'product_format_id');
}
public function product()
{
return $this->format->product;
}
}
ProductFormat
class ProductFormat extends Model
{
public function product()
{
return $this->belongsTo(Product::class);
}
}
Update
The result of dd($this->format); returns an instance of ProductFormat.
After investigating the HasAttributes::getRelationshipFromMethod(), I've noticed that if the property does not exist in the properties attribute of the class, it will try to retrieve a relation, hence the error.
To fix it, I had to add the following to my class:
protected $attributes = ['product'];
Otherwise, I could call product as a function instead of attribute:
$price->product();

laravel 5.1 BelongsTo Reverse call

What i know:
$this->$parent->childs(); //we get childs data
what i want to know how:
$this->child->find($id)->parent(); //how to get childs parent without including model in controller | by just using eloquent
heres my sample code of employee and employeeDependent model:
trait EmployeeRelationships{
public function dependents(){
return $this->hasMany(\App\DB\EmployeeDependent\EmployeeDependent::class);
}
}
trait EmployeeDependentRelationships{
/**
* #return mixed
*/
public function employee(){
return $this->belongsTo(\App\DB\Employee\Employee::class, 'employee_id');
}
}
If you want to get the reverse of a BelongsTo relationship you need to specify the inverse of the relationship on the corresponding model. For example:
Employee Class
class Employee extends Model
{
public dependents()
{
return $this->hasMany(Dependant::class);
}
}
Dependent Class
class Dependent extends Model
{
public employee()
{
return $this->belongsTo(Employee::class, 'employee_id');
}
}
With these relationships defined you can then access the relevant models by calling the appropriate methods like so:
$dependents = Employee::first()->dependents; // Returns an eloquent collection
$employee = Dependent::first()->employee; // Returns a model of type Employee
Note that in this example using the first() method to grab a model, you can can do this with any object of the correct type.

Relationship method must return an object of type Relation (LogicException) Laravel 4.1

I have used Laravel 4 fair bit and it's the first time I've came across this problem.
My pager table:
class pager extends Eloquent
{
protected $table = 'pagers';
public function user()
{
return $this->belongsTo('User', 'bid');
}
public function pager_items()
{
return $this->hasMany('pager_item', 'pid');
}
}
As you can see the pager has many pager items, below is the pager item model which belongs to pager.
class pager_item extends Eloquent
{
protected $table = 'pager_items';
public function pager()
{
return $this->belongsTo('pager', 'pid');
}
}
If I try to insert new model like so:
$test = new pager_item;
$test->description = 'test';
$test->bid =1;
$test->cid =1;
$test->pid =1;
$test->save();
I receive:
LogicException
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
I haven't been able to spot any issues that will cause such error, any help is appreciated, thank you.
in a "belongs to" relation you should try to pass the object to save instead of the id.
$pager = pager::find(10);
$test->pager()->associate($pager);
btw, try to name the classes Uppercase... like
class Pager extends Eloquent
...

Categories