I have the following problem,
I have four models:
MainArea |Institute|institute_level|students with the following reations:
class MainArea extends Model
{
public function institute(){
return $this->belongsTo('\App\Institute');
}
public function places(){
return $this->hasMany('\App\Place');
}
}
class Institute extends Model
{
public function insLevel(){
return $this->hasMany('\App\InstituteLevel');
}
}
class InstituteLevel extends Model
{
public function students(){
return $this->hasMany('\App\Student','applying_level');
}
}
class Student extends Model
{
public function instituteLevel(){
return $this->belongsTo('\App\InstituteLevel','institute_level_id');
}
public function place(){
return $this->belongsTo('\App\Place');
}
}
Now, I want to get all areas with the count of students registered in it, in the same institute? it should be something like this.
$areas=\App\MainArea::withCount('institute.insLevel.students')->where('institute_id',$id)->get();
Any suggestions ?
Unfortunately, "withCount()" doesn't support nested relationships as of Laravel 5.2.
Here's the comment from the contributor in a Github Pull Request.
Related
If I have below models:
class User extends Model{
protected $someDataFromExt = ['taskID0' => 'test', 'taskID1' => 'ting'];
public function tasks() { return $this->hasMany('Task'); }
}
class Task extends Model{
protected $appends = ['ext_data'];
public function user() { return $this->belongsTo('User'); }
public function getExtDataAttribute(){ return $this->external_data; }
}
I would like, when I do: $tasks = auth()->user()->tasks->all(); I want to pass $user->someDataFromExt (based on task ID) to task model, so I later in my $tasks variable I can access:
foreach($tasks as $task){
echo $task->ext_data;
}
Which will return data that was given from user model earlier?
Is this possible? how?
Not completely following why the task data is being stored on the user model, but I think what you’re asking can be achieved via your accessor method on your task model, providing you make the someDataFromExt public:
<?php
class Task extends Model {
public function getExtDataAttribute()
{
return $this->user->someDataFromExt['taskID' . $this->id];
}
}
I have two models:
class Parent extends Model {
public function children(){
return $this->hasMany(Child::class);
}
}
class Child extends Model {
public function parent(){
return $this->belongsTo(Parent::class);
}
}
When I run the following:
$parent = Parent::with(Child::class)->find(1);
I get the following error:
Call to undefined method Illuminate\Database\Query\Builder::child()
Any thoughts on this?
Suppose I got a model with a few relations:
class Author extends Model
{
public function shortStories()
{
return $this->hasMany(ShortStory::class);
}
public function essays()
{
return $this->hasMany(Essay::class);
}
public function books()
{
return $this->hasMany(Book::class);
}
}
Now suppose I got two more models that want to eager load this model with its relations:
class Publisher extends Model
{
public function scopeWithAuthor($query)
{
$query->with('author.shortStories', 'author.essays', 'author.books');
}
}
class Reviewer extends Model
{
public function scopeWithAuthor($query)
{
$query->with('author.shortStories', 'author.essays', 'author.books');
}
}
Problem - if the relations of author change I now need to reflect this in multiple locations.
My question - how do I achieve this in DRY style?
I know that I could add a protected $with to the Author class but then it would always load the relation, not just when required.
With that in mind, one solution I have come up with is to extend the Author model like so:
class AuthorWithRelations extends Author
{
protected $with = ['shortStories', 'essays', 'books'];
}
This then allows me to refactor the scopes of the other models like so:
class Publisher extends Model
{
public function scopeWithAuthor($query)
{
$query->with('authorWithRelations');
}
}
class Reviewer extends Model
{
public function scopeWithAuthor($query)
{
$query->with('authorWithRelations');
}
}
This works well enough but really I was wondering if Laravel provides a better / inbuilt approach to this?
Hello I´m writing an API and I want to display more information about the related model.
Routes.php
Route::resource('makes', 'MakesController');
MakesController.php
class MakesController extends Controller
{
public function index()
{
$data = Make::all();
return response()->json($data);
}
}
This returns only information about the makes (id, name)
but how can I display also how many models has each make?
I have defined these two models
class Make extends Model
{
public function models()
{
return $this->hasMany('App\CarModel');
}
}
class CarModel extends Model
{
public function make()
{
return $this->belongsTo('App\Make');
}
}
You can define $visible field in the Make model's class like this:
protected $visible = ['models'];
This will automatically appends the related model's array to array/json.
You can also use an optional way with makeVisible method:
class MakesController extends Controller
{
public function index()
{
$data = Make::all();
return response()->makeVisible('models')->json($data);
}
}
I didn't know how to ask the question so, the question is not as clear as the description. But here it goes.
I want to query the parent Model, by quering the child Model. Here is the basic Models:
//Gig.php
class Gig extends Eloquent
{
public function gigable()
{
return $this->morphTo('profile');
}
}
//Band.php
class Band extends Eloquent {
public function gigs()
{
return $this->morphMany('Gig','profile');
}
}
//Musician.php
class Musician extends Eloquent {
public function gigs()
{
return $this->morphMany('Gig','profile');
}
}
Now, I know I can do something like this:
Gig::find(1)->gigable
Is there a way that I can retrieve gigables in one query
and for example for my api I can return all the gigable at once.
Something like:
Gig::where('id','>',1)->gigable
I know thats doesn't work.
Such as in reverse of this I can do something like,
Band::with('gigs')->where('created_at','<',Carbon::now())->get();
Use as follows
//Gig.php
class Gig extends Eloquent {
public function gigable()
{
return $this->morphTo();
}
}
//Band.php
class Band extends Eloquent {
public function gigs()
{
return $this->morphMany('Gig','gigable');
}
}
//Musician.php
class Musician extends Eloquent {
public function gigs()
{
return $this->morphMany('Gig','gigable');
}
}
Then you will be able to get the gigs this way:
$band = Band::with('gigs')->where('created_at','<',Carbon::now())->get();
$gigs = $band->gigs;
If this is what you wanted... your question is unclear