2
votes

Consider the following table structure:

user table
id
name
lang_region_id

lang_region table
id
lang_id
region_id

lang table
id
name

region table
id
name

Fairly new to the Laravel framework, but trying to setup Eloquent models and relationships to an existing database. I want to establish the relationship between my user model and the lang and region models. The lang_region table defines what language and region combinations are available and then we can link each user to a valid combination.

I have read through the Laravel documentation several times looking for the proper relationship type, but is seems that the Many to Many and Has Many Through relationships are close, but since our user.id isn't used in the intermediate table I may be out of luck.

Sorry for the amateur question, but just getting used to Laravel and ORMs in general.

2
You should use a pivot table. Then Eloquent works greatMojtaba
That was my initial thought, but it looks like the Eloquent relationships with pivot tables are relying on the ids to exist in the pivot table as well as the tables pivoting on that table. The lang_region table is my pivot table as it includes the lang_id and region_id, but the problem I am looking to solve is that my user table just has a foreign key to a lang_region row and I want access to the lang through the lang_region for a given user.JamieA
Are you sure your database structure is thought through? explain why the lang_region table is the part, there need to be referenced?mrhn
The lang_region table is what determines available localization combinations. Allowing me to to specify US-EN and CA-FR as a valid combinations, but not US-FR. The IDs from these valid combinations are then referenced in the user table.JamieA

2 Answers

2
votes

I would use the lang_region table as both a pivot table and a regular table with its own model.

class LangRegion extends model
{
    protected $table = 'lang_region';

    public function language()
    {
        return $this->belongsTo(Language::class, 'lang_id');
    }

    public function region()
    {
        return $this->belongsTo(Region::class);
    }

    public function users()
    {
        return $this->hasMany(User::class);
    }
}

class User extends model
{
    protected $table = 'user';

    public function langRegion()
    {
        return $this->belongsTo(LangRegion::class);
    }
}

class Language extends model
{
    protected $table = 'lang';

    public function regions()
    {
        $this->belongsToMany(Region::class, 'lang_region', 'lang_id', 'region_id');
    }

    public function users()
    {
        $this->hasManyThrough(User::class, LangRegion::class, 'lang_id', 'lang_region_id');
    }
}


class Region extends model
{
    protected $table = 'region';

    public function languages()
    {
        $this->belongsToMany(Language::class, 'lang_region', 'region_id', 'lang_id');
    }

    public function users()
    {
        $this->hasManyThrough(User::class, LangRegion::class, 'region_id', 'lang_region_id');
    }
}
0
votes

If I understand what you want correctly:

class User extends Model {
   private function lang_region() {
       return $this->hasOne(LangRegion::class)
   }

   public function lang() {
       return $this->lang_region()->lang();
   }

   public function region() {
       return $this->lang_region()->region();
   }
}

class LangRegion extends Model {
   public function lang() {
       return $this->belongsTo(Lang::class);
   }

   public function region() {
       return $this->belongsTo(Region::class);
   }
}