Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HasManyThrough with one-to-many relationship

I am working on small scale CMS for a project with tables like so:

- pages
    - id
    …
- translations
    - page_id
    …
- menus
    - id
    …
- menu_page
    - menu_id
    - page_id
    …

In the Menu model I have this relationship:

function pages(){
    return $this->hasMany('Page');
}

Is it possible to create a relation directly between Menu and Translations that translates to something like this SQL query:

select translations.* 
from translations
inner join menu_page on menu_page.page_id = translations.page_id
where menu_page.menu_id = ?;

Thanks!

like image 272
Thomas Hupkens Avatar asked Feb 13 '23 22:02

Thomas Hupkens


1 Answers

You can't do it with builtin methods, hasManyThrough won't work with many-to-many relation menus-pages.

However you can try a workaround like this:

public function getTranslationsAttribute()
{
    if ( ! array_key_exists('translations', $this->relations)) $this->loadTranslations();

    return $this->getRelation('translations');
}

protected function loadTranslations()
{
    $translations = Translation::join('menu_page', 'translations.page_id', '=', 'menu_page.page_id')
        ->where('menu_page.menu_id', $this->getKey())
        ->distinct()
        ->get(['translations.*','menu_id']);

    $hasMany = new Illuminate\Database\Eloquent\Relations\HasMany(Translation::query(), $this, 'menu_id', 'id');

    $hasMany->matchMany(array($this), $translations, 'translations');

    return $this;
}

Now you can do this:

$menu = Menu::find($id);
$menu->translations; // Eloquent Collection of Translation models

So basically just like you would use any relation. The only trouble is that you can't eager load it.

like image 51
Jarek Tkaczyk Avatar answered Feb 16 '23 02:02

Jarek Tkaczyk