yiic shell doesn't make the relations() as should do
#1
Posted 20 October 2009 - 09:17 AM
Lets say that we have two tables:
Table 1:
Name: Single
Fields: id (PK), someField, someOtherField.
Table2:
Name: CompoundName
Fields: id(PK), idSingle(FK), aField, anotherField
And in mysql I declare a relation bewteen Single and COmpoundName (CompoundName.idSingle -> Single.id)
Well, having this: I do in yiic shell:
model CompoundName
this makes a model called CompoundName (both the file and the class)
and then i do:
model Single
this makes a model named Single. (Both the file and the class)
BUT in the relations() method of single, the following is automatically done by yiic:
return array(
'compoundnames' => array(self::HAS_MANY, 'Compoundname', 'idSingle'),
);
Note that the model name is incorrect!!!
I'm using last svn yii 1.1. Mysql and winXP
The problem is communication! Excess of communication!
#2
Posted 21 October 2009 - 03:02 PM
The problem is communication! Excess of communication!
#3
Posted 22 October 2009 - 07:12 AM
Note that if this is done this way, the latter when we do something like this:
$cn = $single->compoundnames;
The application will say taht the class Compoundname doesn't exists!! (Of course Compoundname doesn't exists!, the one that exists is CompoundName)
Again, note the caps!!!
The problem is communication! Excess of communication!
#4
Posted 23 October 2009 - 09:53 AM
The problem is communication! Excess of communication!
#5
Posted 24 October 2009 - 04:55 PM
PoL, on 23 October 2009 - 09:53 AM, said:
Hey PoL, I will check my Yiic generated code next Tuesday when I am back at work. It could be a windows thing. I work on a linux box so that will be an interesting thing to discover.
I am very new to Yii but I am sure that I can answer this question for you.
I spent a long time trying to figure out how to get models created in
/protected/backend/models/ instead of /protected/models/ but I figured it out and it works.
When I tried Yii on a windows machine many months ago I found the yiic tool a little strange (buggy)but it's pretty slick on linux (I love linux for dev work)
I'll keep you posted
doodle
#6
Posted 27 October 2009 - 07:59 AM
First of all over the weekend I was reading some of the Yii docs (yeah, get a life, I know!) and I came across this little nugget of wisdom here.
Quote
So probably camel case is not a good idea for database use. However I checked my Yiic generated code, and things are working for me the way that you expect them too.
Example
CREATE TABLE IF NOT EXISTS `WebPage` ( `WebPageID` int(11) NOT NULL auto_increment, ... . ... PRIMARY KEY (`WebPageID`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ; CREATE TABLE IF NOT EXISTS `Keyphrase` ( `KeyphraseID` int(11) NOT NULL auto_increment, `KeyphrasePhrase` varchar(50) NOT NULL, PRIMARY KEY (KeyphraseID) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ; CREATE TABLE IF NOT EXISTS `KeyphrasePage` ( `KeyphrasePageID` int(11) NOT NULL auto_increment, `KeyphrasePageKeyphrase` int(11) NOT NULL, `KeyphrasePagePage` int(11) NOT NULL, INDEX(KeyphrasePageKeyphrase), FOREIGN KEY (KeyphrasePageKeyphrase) REFERENCES Keyphrase(KeyphraseID), INDEX(KeyphrasePagePage), FOREIGN KEY (KeyphrasePagePage) REFERENCES WebPage(WebPageID), PRIMARY KEY (KeyphrasePageID) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
Here is a snippet of Yiic generated code
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'keyphrasePages' => array(self::HAS_MANY, 'KeyphrasePage', 'KeyphrasePagePage'),
'pagedatas' => array(self::HAS_MANY, 'Pagedata', 'PagedataPageID'),
);
}
in Yiic generated KeyphrasePage.php
class KeyphrasePage extends CActiveRecord
{
...
.
...
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'keyphrasePageKeyphrase' => array(self::BELONGS_TO, 'Keyphrase', 'KeyphrasePageKeyphrase'),
'keyphrasePagePage' => array(self::BELONGS_TO, 'WebPage', 'KeyphrasePagePage'),
);
}
So it's probably a windoze thing.
doodle
#7
Posted 27 October 2009 - 11:57 AM
#8
Posted 27 October 2009 - 01:24 PM
So, naming tables with '_' to separate words is a good practice? (In OOP, it is better the camel case notation)
No matter, if I need to fix it by myself ok... and if naming tables with '_' to separate words is the way I must go, then ok...
Now I just want your opinion about naming tables and objects, etc...
Thanks!!!
The problem is communication! Excess of communication!
#9
Posted 28 October 2009 - 09:24 AM
I've a problem with auto-generated relations in the model class file. I've defined the relations in my tables, but there were no relations generated in the model file. So I've thought the table relations weren't OK and made a test with the tables, got2doodle gave above (WebPage, Keyphrase, KeyphrasePage).
I need the model files to be in the module "admin", so I ran the commands like this:
model admin.models.WebPage WebPage
model admin.models.Keyphrase Keyphrase
model admin.models.KeyphrasePage KeyphrasePage
Currently I'm using the yii-1.0.10.r1472 release.
Do you have any idea what is the problem ?
Thanks,
Miro
#10
Posted 28 October 2009 - 09:40 AM
@mirrorps: you need to declare foreign key constraints when creating the tables. Otherwise, yii won't have the necessary knowledge to build relations.
#11
Posted 28 October 2009 - 09:43 AM
And I thanks to 'got 2 doodle' for their answers (that doesn't help me in this case, but are good for future reference)
The problem is communication! Excess of communication!
#12
Posted 28 October 2009 - 09:57 AM
These are my db tables:
CREATE TABLE atproduct (
fid int(11) NOT NULL auto_increment,
frcategory int(11) default NULL,
fcode varchar(63) NOT NULL default '',
ftitle_bg varchar(255) NOT NULL default '',
ftitle_en varchar(255) NOT NULL default '',
fprice double NOT NULL default '0',
fpricecorporate double NOT NULL default '0',
fshortdescription_bg text,
flongdescription_en text,
factive int(5) default '1',
fdateadded varchar(25) default NULL,
fdateupdated varchar(25) default NULL,
PRIMARY KEY (fid)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC;
CREATE TABLE atproduct2size (
frproduct int(11) NOT NULL,
frsize int(11) NOT NULL,
PRIMARY KEY (frproduct,frsize),
KEY FK_atproduct2size (frsize),
CONSTRAINT atproduct2size_ibfk_1 FOREIGN KEY (frproduct) REFERENCES atproduct (fid),
CONSTRAINT atproduct2size_ibfk_2 FOREIGN KEY (frsize) REFERENCES atsize (fid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE atsize (
fid int(11) NOT NULL,
fname varchar(5) default NULL,
PRIMARY KEY (fid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I have the constraints for the table atproduct2size, but the relations aren't generated with the command:
model admin.models.Product2size atproduct2size
Any idea what am I doing wrong ?
Regards,
Miro
#13
Posted 29 October 2009 - 09:00 AM
My post in this thread shows sql that did produce relations in the Yiic generated model.
Maybe it helps,
doodle
#14
Posted 29 October 2009 - 09:25 AM
I've saw it earlier. I wanted to ask you, when you ran the shell command model for each table, you gave in your post, did the framework generated the relations for the all 3 model classes, or just for 2 of them?
Thanks again.
Regards,
Miro
#15
Posted 29 October 2009 - 10:03 AM
This is sql code I used
(I have actually modified it again but that doesn't affect this example)
These are the yiic relations
(I added the joinType, I still don't have it all working so the example is incomplete)
// model is webpage
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'keyphrasepages' => array(self::HAS_MANY, 'Keyphrasepage', 'pageid','joinType' => 'INNER JOIN',),
'pagedatas' => array(self::HAS_MANY, 'Pagedata', 'webpageid','joinType' => 'INNER JOIN'),
);
}
// model is keyphrase
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'keyphrasepages' => array(self::HAS_MANY, 'Keyphrasepage', 'keyphraseid'),
);
}
//model is keyphrasepage
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'keyphrase' => array(self::BELONGS_TO, 'Keyphrase', 'keyphraseid'),
'page' => array(self::BELONGS_TO, 'Webpage', 'pageid'),
);
}
take care,
doodle
#17
Posted 29 October 2009 - 12:09 PM
Modified my relations method in webpage model as shown
// model is webpage
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'keyphrasepages' => array(self::HAS_MANY, 'keyphrasepage','pageid'),
'pagedatas' => array(self::HAS_MANY, 'pagedata', 'webpageid'),
);
}
note change of case for model names
in the controller
public function loadwebpage($id=null)
{
if($this->_model===null)
{
if($id!==null || isset($_GET['id']))
// original code // $this->_model=webpage::model()->findbyPk($id!==null ? $id : $_GET['id']);
$this->_model=webpage::model()->with('pagedatas')->findbyPk($id!==null ? $id : $_GET['id']);
if($this->_model===null)
throw new CHttpException(404,'The requested page does not exist.');
}
return $this->_model;
}
In the view I can echo the data field from the pagedata table like this
<?php
foreach( $model->pagedatas as $pagedata)
{
echo $pagedata->data;
}
?>Some things are starting to make sense with some help from others on this forum
doodle
#18
Posted 29 October 2009 - 01:02 PM
lower_case_table_names = 2
#19
Posted 15 December 2009 - 10:24 AM
I am starting a project with a complex (for me) relational database, I want to generate the models and crud skeleton with the yiic tool. Here is an example of three tables that relate.
-- a table for different credit card types CREATE TABLE IF NOT EXISTS `card_type` ( `id` int(11) NOT NULL auto_increment, `name` varchar(50) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ; -- a table for participant info CREATE TABLE IF NOT EXISTS `participant` ( `id` int(11) NOT NULL auto_increment, ... ... ... PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ; -- a table for unique credit card info CREATE TABLE IF NOT EXISTS `participant_credit_card` ( `id` int(11) NOT NULL auto_increment, `participant_id` int(11) default NULL, `card_type_id` int(11) default NULL, `card_number` varchar(50), `card_expiry` date NOT NULL default '0000-00-00', FOREIGN KEY (participant_id) REFERENCES participant(id), FOREIGN KEY (card_type_id) REFERENCES card_type(id), PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ;
Using yiic tool I generate a model for participant like this
>>model participant
this creates the file participant.php under protected/models/
here is the relations part of that file
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'donations' => array(self::HAS_MANY, 'Donation', 'participant_id'),
'event_participants' => array(self::HAS_MANY, 'EventParticipant', 'participant_id'),
'events' => array(self::HAS_MANY, 'Events', 'contact_id'),
'gender' => array(self::BELONGS_TO, 'Gender', 'gender_id'),
'participant_credit_cards' => array(self::HAS_MANY, 'ParticipantCreditCard', 'participant_id'),
'participant_food_healths' => array(self::HAS_MANY, 'ParticipantFoodHealth', 'participant_id'),
'participant_participant_levels' => array(self::HAS_MANY, 'ParticipantParticipantLevel', 'participant_id'),
'participant_programs' => array(self::HAS_MANY, 'ParticipantProgram', 'participant_id'),
);
}
the relevant part of my question is in this line
'participant_credit_cards' => array(self::HAS_MANY, 'ParticipantCreditCard', 'participant_id'),
notice participant_credit_card is now 'ParticipantCreditCard' this is expected based on discussion previously in this thread.
creating the model for participant_credit_card (table name) in yiic I type
>>model participant_credit_card
this creates the file participant_credit_card.php under /protected/models
the class created in this file is class participant_credit_card
class participant_credit_card extends CActiveRecord
{
/**
* The followings are the available columns in table 'participant_credit_card':
* @var integer $id
* @var integer $participant_id
* @var integer $card_type_id
* @var string $card_number
* @var string $card_expiry
*/
do I have to change the class name to particpantCreditCard ? and/or the model filename?
I know the naming conventions are important but I am confused a class named participant_credit_card it seems to me that it should be changed to particpantCreditCard and ParticipantCreditCard.php
any advice would be much appreciated
doodle

Help














