I am trying to get eager loading working when fetching related models.
public function allCompanies() {
$companies = $this->companies()->active()->get();
$companies->load('Industry');
return $companies;
}
I have this function on the model Industry and I believe this should fetch the companies which are within the current industry, it should also fetch the related industry for the companies (this will be the current record)
This doesn't seem to work as when I iterate over the companies it re-fetches the Industry for each one.
Am I doing something wrong with the $companies->load('Industry'); line?
Thanks
Try:
public function allCompanies() {
$companies = $this->companies()->active()->with('industry')->get();
return $companies;
}
The with() and load() functions are referencing functions within the model not the model itself ie:
class Company extends Eloquent {
public function industry()
{
return $this->belongsTo('Industry');
}
}
class Industry extends Eloquent {
public function companies()
{
return $this->hasMany('Company');
}
}
Please reference http://laravel.com/docs/eloquent#eager-loading
Related
I am facing the problem whereby I don't know the syntax of letting the id of my property model equals to property_id value in property_doc table.
In PropertyDoc model
public function property()
{
return $this->belongsTo(Properties::class, 'property_id');
}
In Properties model
public function property_id()
{
return $this->hasMany(PropertyDoc::class, 'property_id');
}
In PropertyController
public function StoreInfoProperty(Request $request)
{
$propertyInfo = new PropertyDoc;
$propertyInfo->property_id = $property_id;
}
I am stuck at retrieving the default id value in properties database to be equal to the property_id in property_docs database. Thank you.
You should change the naming of the relationship, see my example below:
In Properties model
public function propertyDocs()
{
return $this->hasMany(PropertyDoc::class, 'property_id', 'id');
}
In PropertyDoc model
public function property()
{
return $this->belongsTo(Properties::class, 'property_id', 'id');
}
In controller
public function StoreInfoProperty(Request $request)
{
$propertyDoc = PropertyDoc::with(['property'])->where('...logic here');
$property_id = $propertyDoc->property->id;
}
hope can help you and happy coding !
I have a group model and I want to delete groups that don't have any member.
How can I get empty groups with eloquent or SQL query ?
class Group extends Model
{
use HasFactory;
protected $fillable = [
'group_name',
'description'
];
public function users(){
return $this->hasMany(User::class);
}
}
And this is the User model code:
class User extends Model implements AuthenticatableContract, AuthorizableContract
{
use SoftDeletes, Authenticatable, Authorizable, HasFactory, Notifiable;
public function getNameAttribute()
{
return $this->last_name.' '.$this->first_name;
}
public function group(){
return $this->belongsTo(Group::class);
}
}
You can use whereDoesntHave:
Group::whereDoesntHave('users')->delete();
You can make sure that you are deleting the correct groups by running this statement instead:
dump(Group::whereDoesntHave('users')->get());
I think whereDoesntHave work in you situation.
Group::query()->whereDoesntHave('users')->delete();
I'm new to Laravel and I can write simple eloquent queries but have no idea how to convert this query to eloquent. Can anyone give any idea, is it possible to convert this to eloquent or I have to write raw query?
"Select categories.id, categories.name, Sum(likes.liked) as liked
FROM categories, likes
WHERE likes.material_id IN (SELECT category_material.material_id
FROM category_material
WHERE category_material.category_id = categories.id)
GROUP BY categories.id";
Here my Models
class Material extends Model
{
public function categories(){
return $this->belongsToMany(Category::class,'category_material');
}
public function likes(){
return $this->hasMany(Like::class);
}
////////////////////////////////////////////////////////////
class Like extends Model
{
protected $table = 'likes';
public function user(){
return $this->belongsTo(User::class);
}
public function material(){
return $this->belongsTo(Material::class);
}
//////////////////////////////////////////////////////
class Category extends Model
{
public function materials(){
return $this->belongsToMany(Material::class,'category_material');
}
You can define a likes relationship in your Category model like so:
public function likes()
{
return $this->belongsToMany(Like::class, 'category_material', 'category_id', 'material_id', 'id', 'material_id');
}
Then to achieve what you're after with Eloquent you can use a mixture of has() and withCount, however, we're going to modify the withCount call to return a sum() instead:
$catrgories = Category::has('likes')->withCount([
'likes as liked' => function ($query) {
$query->select(DB::raw('SUM(likes.liked)'));
},
])->get();
If you're wanting to return categories that don't have any likes you can remove the has() method, and introduce the COALESCE() function to your raw query:
$catrgories = Category::withCount([
'likes as liked' => function ($query) {
$query->select(DB::raw('COALESCE(SUM(likes.liked), 0)'));
},
])->get();
Alternatively, you could simply load the necessary relationships and then use that fact that Eloquent returns collection to get the value after you've retrieved the results from the database:
$categories = Category::with('materials.likes')->get()->map(function ($item) {
$item->setAttribute('liked', $item->materials->map(function ($item) {
return $item->likes->map->sum('liked')->sum();
})->first());
$item->unsetRelation('materials');
return $item;
});
This would mean that you don't have to add the custom relationship.
I need to do a where condition on the code field from my intermediate table. My two models are;
class Agreement extends Eloquent {
protected $table = 'agreements';
public function clients(){
return $this->belongsToMany('Client', 'client_agreements')->withPivot('start_date', 'expire_date', 'code');
}
}
And;
class Client extends Eloquent {
public function agreements(){
return $this->belongsToMany('Agreement', 'client_agreements')->withPivot('start_date', 'expire_date', 'id', 'code');
}
}
My controller is currently;
public function show($code, $client_id)
{
//
$client = Client::with('agreements')->find($client_id);
$client_agreement = $client->agreements;
}
I think I need to expand the $client->agreements; code to include a where condition on the $code. I have tried so many different combinations but just keep returning the same Call to undefined method error.
I've tried things like;
$client_agreement = $client->agreements->where('code', '=', $code);
$client_agreement = $client->agreements->code->find($code);
$client_agreement = $client->agreements->pivot->code->find($code);
I always get the same error. I'm not that great on objects so maybe I'm looking at this all wrong. How is it done?
You need to access ->relation() not ->relation (which is dynamic property call):
$client_agreement = $client->agreements()
->wherePivot('code', '=', $code)
->first();
I've been having a look at phalcon as an alternative to a laravel project that I'm running. It's mainly a REST api. I'm trying to figure out how to include relationships in a json response for models.
For example, if I had 2 models, set up like below:
class Clients extends \Phalcon\Mvc\Model
{
public function initialize() {
$this->hasMany('clientid','Contacts','clientid')
}
}
class Contacts extends \Phalcon\Mvc\Model {
public function initialize() {
$this->belongsTo('clientid','Clients','clientid')
}
}
And I did a:
$clients = Client::find();
return json_encode($clients->toArray());
How would I get it to automatically include the contacts?
I need to output to be something like this:
[{
clientid:'1111',
contacts:[
{
contactid:111
}
]
}];
Many thanks!
From the docs:
By accessing an attribute with the same name as the relationship will retrieve all its related record(s).
Based on the above, you should be able to access the contacts via the relationship defined like so:
$clients = Client::find();
$clientContacts = $clients->contacts;
// do something with the contacts
Edit:
Try to loop through your $contacts and then get the related record(s):
foreach ($clients as $client) {
// Do something with the contacts...
$contacts[$client->id] = $client->contacts;
}