razn
razn

Reputation: 69

How to get parent with only the first child in using eloquent orm?

I'm trying to get the active(i.e active = 1) albums from my album table which has at least 1 active image with the first active image in descending order of date created. i.e the each album's image must be the last active image to be created.

My Album model is:

class Album extends Model {
    public function images()
    {
        return $this->hasMany('Images','album_id');
    }

    public function scopeActive($query){
        return $query->where('is_active', 1);
    }
}

My Images Model is:

class Images extends Model {

    public function scopeActive($query){
        return $query->where('is_active', 1);
    }

    public function album(){
        return $this->belongsTo('Album', 'album_id', 'id');
    }

}

So far I've come up with the following:

$albums = Album::with(['images' => function($query){
            $query->orderBy('created_at', 'desc');
            $query->first();
        }])
        ->whereHas('images', function ($query) {
            $query->active();
        })
        ->active()
        ->get();

The above result would give me the following array with image for only one album:

Array
(
[0] => Array
    (
        [id] => 2
        [name] => Test Gallery
        [slug] => test-gallery
        [description] => this is test gallery
        [cover_image] => 
        [is_active] => 1
        [created_by] => 2
        [updated_by] => 2
        [deleted_at] => 
        [images] => Array
            (
            )

    )

[1] => Array
    (
        [id] => 3
        [name] => My Gallery 2
        [slug] => my-gallery-2
        [description] => Hello, this is my second gallery.
        [cover_image] => 
        [is_active] => 1
        [created_by] => 2
        [updated_by] => 
        [deleted_at] => 
        [images] => Array
            (
                [0] => Array
                    (
                        [id] => 9
                        [album_id] => 3
                        [image] => gallery_xfWjm0JuzZ.jpg
                        [description] => 
                        [is_active] => 1
                        [created_by] => 2
                        [updated_by] => 
                        [deleted_at] => 
                    )

            )

    )

)

Can anyone help me to achieve what I'm trying to do.

Upvotes: 0

Views: 1394

Answers (2)

Cong Chen
Cong Chen

Reputation: 2436

All you need is whereHas method:

$albums = Album::whereHas('images', function ($query) {
    $query->where('is_active', 1)->orderBy('created_at', 'desc');
})->get();

It'll retrieve all albums that have at least one active image

Upvotes: 0

Mihai Matei
Mihai Matei

Reputation: 24276

you should try something like:

class Album extends Model
{
    public function image()
    {
        return $this->images()
            ->active()
            ->orderBy('created_at', 'desc')
            ->take(1)
            ->first();
    }

    public function images()
    {
        return $this->hasMany('Images','album_id');
    }

    public function scopeActive($query){
        return $query->where('is_active', 1);
    }
}

$albums = Album::active()->whereHas('images', function ($query) {
    $query->active();
})->get();

foreach ($albums as $album) {
    var_dump($album->image());
}

Upvotes: 1

Related Questions