Many-to-many relationships – Phalcon

If you are working with Phalcon, you will probably need to establish a many-to-many relationship between models. While i was searching in the official documentation, this was not very clear for me at that time. I posted this question on the form, and i got the correct answer.

I will explain you here, step by step. As an example, we will think about the following database structure:

Article table:

CREATE TABLE IF NOT EXISTS `article` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
  `content` text CHARACTER SET latin1,
  `slug` varchar(160) CHARACTER SET latin1 NOT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `title` (`title`,`created_at`),
  KEY `slug` (`slug`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;

Category table:

CREATE TABLE IF NOT EXISTS `category` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET latin1 NOT NULL,
  `slug` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
  `left_node` int(11) NOT NULL,
  `right_node` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`),
  KEY `idx_slug` (`slug`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;

articles_categories table:

CREATE TABLE IF NOT EXISTS `articles_categories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `article_id` int(11) NOT NULL,
  `category_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `article_id` (`article_id`),
  KEY `category_id` (`category_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

ALTER TABLE `articles_categories`
  ADD CONSTRAINT `articles_categories_ibfk_1` FOREIGN KEY (`article_id`) REFERENCES `article` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `articles_categories_ibfk_2` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

Article model:

<?php

namespace Models;

class Article extends Phalcon\Mvc\Model
{

  public function initialize()
  {
    $this->hasManyToMany(
      "id",
      "Models\ArticlesCategories",
      "article_id",
      "category_id",
      "Models\Category",
      "id",
      array('alias' => 'categories')
    );
  }
}

Category model:

<?php

namespace Models;

class Category extends Phalcon\Mvc\Model
{

  public function initialize()
  {
    $this->hasManyToMany(
      "id",
      "Models\ArticlesCategories",
      "category_id",
      "article_id",
      "Models\Article",
      "id",
      array('alias' => 'articles')
    );
  }
}

ArticlesCategories model:

<?php

namespace Models;

class ArticlesCategories
{

  public function initialize()
  {
    $this->belongsTo('category_id', 'Models\Category', 'id', 
      array('alias' => 'category')
    );
    $this->belongsTo('article_id', 'Models\Article', 'id', 
      array('alias' => 'article')
    );
  }
}

Easy, huh ? See the original post. I hope this was helpful :)

Share and Enjoy

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

3 Comments

  • Bob
    06/11/2014 - 01:25 | Permalink

    the code blocks are all black background on a slightly off black text. couldn’t read.

  • Boris
    27/03/2014 - 21:25 | Permalink

    This works weirdly for me.

    And how do you save article categories when u add a new article?

    It adds some other records for me in my article category table.. Not sure why. It’s always double, feels like it adds IDs of category table as well

  • Josef Svoboda
    11/02/2014 - 14:51 | Permalink

    Hi man!
    Thanks for your contribution, did you somehow solved situation, when “articles_categories” is not just a simple mapping table, but has i.e. another attributes? Like “date_created”?

    They got it in documentation with Robots, RobotsParts and Parts. RobotParts is mapping table and contains date_created.

    When i do something like:


    $robot = Robots::findFirst(‘name = “Robo Cop”‘);

    $parts = array();
    $parts[0] = new Parts();
    $parts[0]->name = ‘xxx’;
    $parts[1] = new Parts();
    $parts[1]->name = ‘yyy’;

    $robot->parts = $parts;
    $robot->save();

    I don’t see how can i set the mapping table attributes..
    Thanks, Josef

  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    *


    one + = 2

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>