Combining 2 related tabled into 1 model

Hello,

I have 2 tables containing related information.




                ++++++++++++++++++++ 

+++++++++++     + page_translation +

+  page   +     ++++++++++++++++++++     ++++++++++++

+++++++++++     +        id        +     + language +

+   id    + <-- +      page_id     +     ++++++++++++

+ visible +     +      lang_id     + --> +    id    +

+   ...   +     +       title      +     +   code   +

+++++++++++     +      contents    +     ++++++++++++

                +        ...       +

                ++++++++++++++++++++



Every page has some of its’ contents language specific.

So I want to have one model, that will be constructed depending on the current language.

Is it right to do what I want? And if yes, how I can combine variables in one model?

Thanks in advance!

Hi Arman,

Here’s a test example for you. I may name it ‘the way i’d start to make it’ :)

First step, db scheme





CREATE TABLE IF NOT EXISTS `page` (

  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,

  `visible` enum('y','n') NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8;




CREATE TABLE IF NOT EXISTS `lang` (

  `id` char(2) NOT NULL,

  `name` varchar(125) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;




CREATE TABLE IF NOT EXISTS `translation` (

  `page_id` int(11) unsigned NOT NULL,

  `lang_id` char(2) NOT NULL,

  `title` varchar(255) NOT NULL,

  `content` text NOT NULL,

  PRIMARY KEY (`page_id`,`lang_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;




ALTER TABLE `translation`

  ADD CONSTRAINT `translation_lang` FOREIGN KEY (`lang_id`) REFERENCES `lang` (`id`),

  ADD CONSTRAINT `translation_page` FOREIGN KEY (`page_id`) REFERENCES `page` (`id`);



Add some data to these tables

Second step, create models and controllers

With gii it’ll take seconds to create Page, Translation models and CRUD for Page

Third step, edit your models

Translation model, add




 	public function primaryKey() {

        return array('page_id', 'lang_id');

    }



Page model, add





    public $title;

    public $content;


    public function defaultScope() {

        return array(

            'select'=>'t.id, t.visible, tr.title, tr.content',

            'join'=>"LEFT OUTER JOIN translation as tr ON tr.page_id=t.id AND tr.lang_id='" . Yii::app()->language . "'",

        );

    }



Forth step, edit your view file

/views/page/_view, add





	<b><?php echo CHtml::encode($data->getAttributeLabel('title')); ?>:</b>

	<?php echo CHtml::encode($data->title); ?>

	<br />

	<b><?php echo CHtml::encode($data->getAttributeLabel('content')); ?>:</b>

	<?php echo CHtml::encode($data->content); ?>

	<br />



Final step

switch ‘language’=>‘en’ to a desired one (I decided to use simplified language form for now, I mean not ‘en_us’) and check how it influences your output at page/index

[i]

Hope I didn’t forget any detail and it’ll help you find your way to code multi-lang support.[/i][i][b]

[/b][/i]

[i]

[/i]

Regards,

Yuga

Hello Yuga and thanks for your response.

This will surely work, but I think there must be another approach. I’ve heard that it’s not recommended to use queries in named scopes and default scope. They must be used only for criteria (condition).

Another problem with this approach would be that it won’t work for update, insert and delete queries. So I will have to write functions for them separately. Default scope would appropriate approach to set language condition though.

Is there any other approach to achieve the same result?

Hi,

Please clarify what do you mean by queries, cause I don’t see any additional queries in the example’s defaultScope() .

Yes, you’ll need to figure out all additional operations, that was only a start-point example.

And of course it’s only one of possible ideas to implement.

Regards

By saying queries I mean SQL query that selects (does something) something. I’ve heard that scopes are recommended only for conditions, that goes in WHERE clause.

Quote from @qiang

And here is the link where I’ve read it (see Comment 1).

Yes, in that example there IS another query to db and the problem clearly described by the issue’s opener.

Query is a query, it’s not a query criterias which are used in my example, so I don’t think it’s related.