Cons and Pros of having a model class for a association table

Hi,

I’m pretty new to Yii and I have the following situation;

There are three tables in my case;

color, painting and painting_color where each color can have many paintings and each painting can have many colors. There will be some advanced filtering; such as finding the paintings which contain the colors; "yellow", "red" and "green".

The book that I have been following (Agile Web Application Development with Yii and PHP5) says that it’s not necessary to create a model for every association table, however, some people in the forum recommends the opposite; as in these posts;

http://www.yiiframework.com/forum/index.php/topic/19959-handling-many-to-many-relationships/page__p__97706__hl__many+many+relation+hip#entry97706

http://www.yiiframework.com/forum/index.php?/topic/19948-many-to-many-with-input-field/page__pid__97646#entry97646

Now,

[b]If I choose to use a model class for the association table, would it cause any performance problems?

If I choose to handle the relation without using a model class, can I face any complexity issues in the long term when there are many filtering attributes such as color, size, orientation, origin etc?[/b]

Please tell me the cons and pros of going with each method.

Thank you.

tbl_color (model: Color)


id

tbl_painting (model: Painting)


id

tbl_painting_color (model: [color="#FF0000"]PaintingColor?[/color])


(painting_id, color_id)

As long as you don’t fetch thousands of records in a single request (which is unlikely if you are not doing any big bulk inserts etc.) you won’t notice performance issues. ActiveRecord is very fast so performance is often not an appropriate argument against it. However…

My personal opinion: You have to think about this from another point of view: Does it make sense to filter on an association table model by color, size etc. or isn’t that something that could be associated with the painting itself (or the color respectively?). The crosstable is just that, a quite simple association there is no real logic behind that as long as you don’t have any additional information in there. So I personally would not use an ActiveRecord for that but rather use something like the code below




class Painting extends CActiveRecord {


        public function associateWithColor(Color $color)

        {

            //insert the $color->id into your crosstable where the painting_id=$this->id and you are done

        }

        

        public function removeColor(Color $color)

        {

            //delete the color_id=$color->id row from your crosstable where the painting_id=$this->id

        }

        

        public function search()

        {

            //create a CDBCriteria that uses JOINS to filter using the crosstable entries by color etc.

        }

}

In your PaintingController you could have an action like




        public function actionAssociateWithColor($id,$colorid)

        {

            $color=$this->loadColor($colorid);

            $model=$this->loadPainting($id);

            $model->associateWithColor($color);

        }



the request painting/associateWithColor?id=1&colorId=2 will associate painting 1 with color 2 now

Hope it helps a bit,

Hannes

This is exactly what is recommended in the book that I have been following. Using Yii’s DAO directly in related models to insert, delete or update associations.

What I would like to know is that in which cases one should always create model classes for association tables? Would it be that if the association table is a domain object of our application?

such as;




**************            ***************               ****************

* Customer   *            * Purchase    *               * Product      *

**************            ***************               ****************

* id         *------------* id          *---------------* id           *

*            *            * customer_id *               *              *

*            *            * product_id  *               *              *

**************            ***************               **************** 



or if it has extra columns along with the relations?




**************            *****************               ****************

* Customer   *            * Shopping Cart *               * Product      *

**************            *****************               ****************

* id         *------------* customer_id   *---------------* id           *

*            *            * product_id    *               *              *

*            *            *               *               *              *

*            *            * quantity      *               *              *

**************            *****************               ****************



I would say you should think about using a dedicated modelclass if there is more logic behind it than just a simple association between two entities. And yes, a shopping card might be an example if you have additional fields like purchase time, amount, aggregrated price sum etc. and you want the user to interact with this shopping card via a form to put in some additional info. In such a case I would tend to use a model to make use of ActiveRecords validation rules etc. In all other cases I wouldn’t use one, just for the sake of simplicity.

Thanks Hannes, that makes sense. I think I won’t use models for my association tables until the requirements demand more complexity.

Good explanation Haensel. I struggled with this a while back and ended up refactoring my tables to eliminate the association table.