inheritance - Derived classes with ActiveRecord in Yii -
i working following database design, , wanted understand how can best address in yii.
+---------------+----------------+---------------------+ | table | column name | column type | +---------------+----------------+---------------------+ | question | id | int | | | description | text | | | type | enum('mcq', 'text') | | | | | | | | | | mcq_question | id | int | | | question_id | int | | | option1 | text | | | option2 | text | | | option3 | text | | | option4 | text | | | correct_answer | option1 | | | | | | | | | | text_question | id | int | | | question_id | int | | | answer | text | +---------------+----------------+---------------------+
the idea have different kind of questions mcq, text, grid, true/false etc. common data can captured in "question" table, while specifics can captured in respective tables. in simple programming concepts, easy map structure "question" class base class other classes "mcq_question", "text_question" etc. types of such questions may increase in future, hence need flexibility.
with above approach, can use "question_id" foreign key relationships other tables, rather working each individual table, make code more complex.
from understood reading of articles, approach doesn't work yii: http://www.yiiframework.com/forum/index.php/topic/23405-cactiverecord-inheritance-and-dynamic-attributes/
is there no way yii? if not, of workarounds problem keep code simple.
regards, kapil
the link refer not apply question. can create derived classes , override tablename()
-function load out of correct table.
first of all, in situation not use different ids derived types, use same id. 1 question_id lot easier maintain (and store answers for). remove auto_increment derived tables id field , remove question_id. assuming that:
a minimalised example mcq_question:
class mcq_question extends question { public $description = ''; public $type = 'mcq'; function tablename() { return 'mcq_question'; } }
there 2 issues remaining: 1) generic function in base class loads specific question 2) if save derived class, should update/create question instance
1) easy, might have add array "convert" between enum , class name:
class question extends cactiverecord { public function findbyid($questionid) { $types = array('mcq' => 'mcq_question'); $question = $this->findbypk($questionid); if ($question && array_key_exists($question->type, $types) { $class = $types[$question->type]; return $class::model()->findbypk($question->id); } } }
the array links not graceful solution, trick. can add static it's more clear have updated, , on.
2) can accomplish overriding beforesave()
-function in derived classes.
public function beforesave() { if ($this->isnewrecord) { $question = new question(); $question->type = $this->type; $question->description = $this->description; $question->save(); $this->id = $question->id; } // else check if perhaps description changed , update ...
this not code need again, it's not job yours ;)
it should started though. beforesave end pretty same everywhere if php recent enough, in trait
.
Comments
Post a Comment