41

For example in one-to-many due to documentation (http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#relational-data) you can link two models in this way (one-many = company-zone):

$defaultZone = new Zone;
$defaultZone->name = Zone::DEFAULT_ZONE;
$company->link('zones', $defaultZone);

But how it works for many-to-many relations when you have transit table like tbl_user_market(user_id, market_id)?

johnsnails
  • 1,971
  • 20
  • 29
raiym
  • 1,439
  • 1
  • 28
  • 54

1 Answers1

86

When using a junction table for many-to-many relations, you have to

  1. Define the relations
  2. Link the two models together

In the User model define the following relation function:

public function getMarkets() {
    return $this->hasMany(Market::className(), ['id' => 'market_id'])
      ->viaTable('tbl_user_market', ['user_id' => 'id']);
}

In the Market model define the following relation function:

public function getUsers() {
    return $this->hasMany(User::className(), ['id' => 'user_id'])
      ->viaTable('tbl_user_market', ['market_id' => 'id']);
}

And finally, after saving both models, link them together:

$user = new User;
$user->name = 'Foo';
$user->save();

$market = new Market;
$market->name = 'Bar';
$market->save();

$user->link('markets', $market);

The call to link() will populate the junction table.

Reference: http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#link()-detail

vim
  • 1,540
  • 12
  • 16
  • @onegun: When you call save() on a model, Yii determines whether to perform an update or insert query. That's the beauty of such a framework, you don't have to worry about things like that anymore. – vim Dec 19 '14 at 21:01
  • 2
    I created a behavior to help saving multiple links - http://github.com/cornernote/yii2-linkall `User::findOne(1)->linkAll('markets', [Market::findOne(2), Market::findOne(3)], true);`, it looks after removing old links and adding the new ones. – cornernote Jun 20 '15 at 02:00
  • 4
    You can also use ManyToMany Behavior. See: https://github.com/voskobovich/ManyToManyBehavior – Antonín Slejška Dec 01 '15 at 15:08
  • 1
    @vim, Could you please add to your answer how to load the Market entity with pre-populated 'users' attribute? – milkovsky Feb 01 '16 at 14:22