We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Hello people , I'm having problems in relationship many to many save and also with self-relationship.

I would like to put together a complete crud with relationships: Groups Users and Proposals

This does not save on GroupUsers. [UsuariosGrupos]

I am sorry for my english

My database relationship

link
 https://ibb.co/jMZavw

<?php

namespace Some;

use Phalcon\DI,
    Phalcon\Db\Column,
    Phalcon\Db\RawValue,
    Phalcon\Mvc\Model,
    Phalcon\Events\Manager as EventsManager,
    Phalcon\Db\Adapter\Pdo\MySQL as Connection,
    Phalcon\Mvc\Model\Manager as ModelsManager,
    Phalcon\Mvc\Model\Metadata\Memory as ModelsMetaData;

$eventsManager = new EventsManager();

$di = new DI();

$connection = new Connection(array(
    "host"     => "localhost",
    "username" => "jan",
    "password" => "1817698",
    "dbname"   => "socius",
));

$connection->setEventsManager($eventsManager);

$eventsManager->attach('db1',
function ($event, $connection) {
        switch ($event->getType()) {
            case 'beforeQuery':
                echo $connection->getSqlStatement(), "\n";
                print_r($connection->getSqlVariables());
                break;
        }
    }
);

$modelsManager = new ModelsManager();
$modelsManager->setDi($di);
$di['db1'] = $connection;
$di['modelsManager'] = $modelsManager;
$di['modelsMetadata'] = new ModelsMetadata();

//Model Proposals

class Propostas extends Model {

    public $id;
    public $proposta;
    public $vinculada;
    public $aceitada;
    public $rejeitada;

    public function initialize() {
        $this->setConnectionService('db1');
        //auto-relacionamento
        $this->belongsTo('propostas_id', 'Propostas', 'id', ['alias' => 'proposta']);
        $this->belongsTo('usuarios_id', 'Usuarios', 'id');
        $this->belongsTo('grupos_id', 'Grupos', 'id');
    }

}

//Model UsersGroups

class UsuariosGrupos extends Model {

    public $id;
    public $usuarios_id;
    public $grupos_id;
    public $status_admin;

    public function beforeCreate() {
        $this->status_admin = true;
    }
    public function initialize() {
        $this->setConnectionService('db1');
        $this->belongsTo('usuarios_id', 'Usuarios', 'id', ['alias' => 'Usuario']);
        $this->belongsTo('grupos_id', 'Grupos', 'id', ['alias' => 'Grupo']);
    }
}

//Model Groups

class Grupos extends Model {
    public $id;
    public $nome;
    public $tema;
    public function initialize() {
        $this->setConnectionService('db1');
        $this->useDynamicUpdate(true); 
        $this->hasMany('id', 'Propostas', 'grupos_id');
        $this->hasMany('id', 'UsuariosGrupos', 'grupos_id', ['alias' => 'UsuariosGrupos']);
        $this->hasManyToMany('id','UsuariosGrupos', 'grupos_id', 'usuarios_id', 'Usuarios','id', ['alias' => 'Usuarios']);
    }
}

//Model Users

class Usuarios extends Model {

    public $id;
    public $email;
    public $nome;
    public $senha;
    public function initialize() {
    $this->setConnectionService('db1');
    $this->useDynamicUpdate(true); 
        $this->hasMany('id', 'Propostas', 'usuarios_id');
        $this->hasMany('id', 'UsuariosGrupos', 'usuarios_id', ['alias' => 'UsuariosGrupos']);
        $this->hasManyToMany('id', 'UsuariosGrupos','usuarios_id', 'grupos_id', 'Grupos', 'id',['alias' => 'Grupos']);
    }

}

$usuarios = Usuarios::findById(1);
$grupos= new Grupos();
$grupos->nome = "grupo do x";
$grupos->tema = "tema";
$grupos->Usuarios = array($usuarios);
$grupos->save();

//example update, delete, find with Group [Grupos]  , Users [Usuarios] and Proposals [Propostas] 
// in which it saves in UsersGroups "UsuariosGrupos"

Thanks in advance

edited Nov '17

Hi @uendelflavio

First Propostas table don't have propostas_id column and your model have this

Second, try this

if ($grupos->save()) {
    echo "nice!!! group saved!";
} else {
    echo "wrong! group didn't save. Details: ". implode(' ', $grupos->getMessages());
}

If didn't save you can get some explanations about

I hope its helps you. Good luck

edited Nov '17

Hi Degiovanni Emilio thanks for answering

ok,you are right and proposals contain self-relationship.

this and the new structure of my database:

link: https://ibb.co/gbpyyG

I need to assemble the entire structure of the models correctly in phalcon, but it does not work, or it works wrong

<?php
//my test

$usuarios = new Usuarios();
$usuarios->nome = 'ufsm';
$usuarios->email = '[email protected]';
$usuarios->senha = '12345';

$grupos = new Grupos();
$grupos->nome = "grupo do x";
$grupos->tema = "tema";
$grupos->Usuarios = array($usuarios);
$grupos->save();

//error

PHP Fatal error:  Uncaught exception 'Phalcon\Mvc\Model\Exception' with message 'Model 'UsuariosGrupos' could not be loaded' in /home/uendel/teste_hasmanytomany_phalcon.php:122
Stack trace:
#0 [internal function]: Phalcon\Mvc\Model\Manager->load('UsuariosGrupos', true)
#1 [internal function]: Phalcon\Mvc\Model->_postSaveRelatedRecords(Object(Phalcon\Db\Adapter\Pdo\Mysql), Array)
#2 /home/uendel/teste_hasmanytomany_phalcon.php(122): Phalcon\Mvc\Model->save()
#3 {main}
  thrown in /home/uendel/teste_hasmanytomany_phalcon.php on line 122

I believe that the table 'UsuariosGrupos' should write in the fields usuario_id and groups_id automatically

well to prevent any dummy error always use alias in all relationships

you have an error in your loader, because don't find UsuariosGrupos class check the loader docs

yes now the tables Usuarios, Grupos and UsuariosGrupos are working perfectly with the following change:

class Propostas extends Model {

    public $id;
    public $proposta;
    public $vinculada;
    public $aceitada;
    public $rejeitada;

    public function initialize() {
        $this->setConnectionService('db1');
        //auto-relacionamento
        $this->belongsTo('propostas_id', Propostas::class, 'id', ['alias' => 'proposta']);
        $this->belongsTo('usuarios_id', Usuarios::class, 'id');
        $this->belongsTo('grupos_id', Grupos::class, 'id');
    }

}

class UsuariosGrupos extends Model {

    public $id;
    public $usuarios_id;
    public $grupos_id;
    public $status_admin;

    public function beforeCreate() {
        $this->status_admin = true;
    }
    public function initialize() {
        $this->setConnectionService('db1'); 
        $this->belongsTo('usuarios_id', Usuarios::class, 'id', ['alias' => 'Usuario']);
        $this->belongsTo('grupos_id', Grupos::class, 'id', ['alias' => 'Grupo']);
    }
}

class Grupos extends Model {
    public $id;
    public $nome;
    public $tema;
    public function initialize() {
        $this->setConnectionService('db1');
    $this->useDynamicUpdate(true); 
        $this->hasMany('id', Propostas::class, 'grupos_id');
        $this->hasMany('id', UsuariosGrupos::class, 'grupos_id', ['alias' => 'UsuariosGrupos']);
        $this->hasManyToMany('id',UsuariosGrupos::class, 'grupos_id', 'usuarios_id', Usuarios::class,'id', ['alias' => 'Usuarios', 'foreignKey' => true]);
    }
}

class Usuarios extends Model {

    public $id;
    public $email;
    public $nome;
    public $senha;
    public function initialize() {
        $this->setConnectionService('db1');
    $this->useDynamicUpdate(true); 
        $this->hasMany('id', Propostas::class, 'usuarios_id');
        $this->hasMany('id', UsuariosGrupos::class, 'usuarios_id', ['alias' => 'UsuariosGrupos']);
        $this->hasManyToMany('id', UsuariosGrupos::class,'usuarios_id', 'grupos_id', Grupos::class, 'id',['alias' => 'Grupos', 'foreignKey' => true]);
    }

Using syntax "Usuarios::class" and loaded automatically.

but still need to test the self-relationship of the table Propostas