how to define two foreign keys in cakePHP - cakephp

I got a table with a few columns.
The table has a primary key (replyid), and two foreigne keys (userid and postid).
Here is the structure of the table:
{replyid, content, userid, postid}
The Reply table got two foreigne keys.
I am not sure if this is a correct to set the foreign keys like this:
class Post extends AppModel{
var $name = 'Post';
var $useTable = 'post';
var $primaryKey = 'postid';
var $belongsTo = 'User';
var $hasMany = array(
'Reply' => array(
'className' => 'Reply',
'foreignKey' => 'postid',
'foreignKey' => 'userid'
)
);
}
?>
Could you helpplease?

Two foreign keys are fine,but you should define the relationshions in right models.
In your post model,
var $hasMany = array(
'Reply' => array(
'className' => 'Reply',
'foreignKey' => 'postid',
//'foreignKey' => 'userid'
)
);
In your user model,
var $hasMany = array(
'Reply' => array(
'className' => 'Reply',
//'foreignKey' => 'postid',
'foreignKey' => 'userid'
)
);

Unfortunately CakePHP does not support composite keys or partial primary keys. As recommended by the CakePHP manual, you can either use direct query calls such as:
CREATE TABLE posts_tags (
id INT(10) NOT NULL AUTO_INCREMENT,
post_id INT(10) NOT NULL,
tag_id INT(10) NOT NULL,
PRIMARY KEY(id));
...Or, you can create a surrogate key, perhaps an auto-increment value. Rather than using an auto-increment key as the primary key, you may also use char(36). CakePHP will then use a unique 36 character uuid (String::uuid) whenever you save a new record using the Model::save method. (From CakePHP Manual)

Build your tables in the database and use cake bake to build the models - this way you'll see how Cake handles it natively. I recommend that you name your db columns like foreign_id. It'll make life a lot easier.

Related

CakePHP : 1054 Unknown column 'User.id' in 'field list'

I am learning CakePHP. There, I am stuck with following problem:
I have a table called comments with fields comment_id, comment_title, comment_text, comment_date & user_id.
Also I have my users table with fields user_id, user_name, user_email, created_date.
Then in my User model I am trying to create a hasMany relationship like :
var $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'user_id'
), );
But this giving me an error
1054 Unknown column 'User.id' in 'field list'
I know this is because I don't have an id column in my users table instead I have user_id
Now, my question is : is there a way to fix this without renaming the user_id field of user table? As this will require change in every existing code where I have used user_id ?
Set in your User model:
public $primaryKey = 'user_id';
If you need create some relationship and models, controller, views.. You can use Bake shell, see: http://book.cakephp.org/2.0/en/console-and-shells/code-generation-with-bake.html
To avoid this kind of errors use foreign key constraints in database.
Cakephp automatically add associations between tables.
public $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'user_id',
'conditions' => array('Comment.user_id' => 'User.user_id'),
'dependent' => true
)
);

CakePHP using foreign keys with different names as the associated primary keys

I set up more than one models, which i want to associate with a master-model like this:
class CommonType extends AppModel {
public $useDbConfig = 'common';
public $hasOne = array(
'CommonTypeDescription' => array(
'className' => 'CommonTypeDescription',
'foreignKey' => 'type_description_id',
'dependent' => true
),
'CommonTypeExperience' => array(
'className' => 'CommonTypeExperience',
'foreignKey' => 'type_expirience_id',
'dependent' => true
),
'CommonTypeProperty' => array(
'className' => 'CommonTypeProperty',
'foreignKey' => 'type_property_id',
'dependent' => true
),
);
public $belongsTo = array(
'CommonTypeCategory' => array(
'className' => 'CommonTypeCategory',
'foreignKey' => 'common_type_id',
));
}
In Heidi SQL (for example) i set the foreignkeys for the tables type_experiences, type_properties and type_descriptions as above, so that foreignkeys in my code and in my tables have the same name.
But now, i don't want to name the primary key as the foreign key, the primary key of the (e.g.) type_descriptions table should named "id". This is the model of type_description:
class CommonTypeDescription extends AppModel {
public $name = 'CommonTypeDescription';
public $useDbConfig = 'common';
public $useTable = 'type_descriptions';
public $primaryKey = 'id';
}
and here is the database creation code:
CREATE TABLE `type_descriptions` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`common_type_id` INT(11) NULL DEFAULT NULL,
`short_description` VARCHAR(50) NULL DEFAULT NULL,
`long_description` VARCHAR(50) NULL DEFAULT NULL,
`notes` VARCHAR(50) NULL DEFAULT NULL,
`modified` DATETIME NULL DEFAULT NULL,
`created` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `type_description_id` FOREIGN KEY (`common_type_id`) REFERENCES `common_types` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION) ...
But when i try to get the data from my model CommonType ($this->find('all')) i get an error like "Unknown column 'CommonTypeDescription.type_description_id' in 'on clause'"
First, i thought that i have to declare the primary key of the description model as "id", but it seams, that the foreign key definition overwrites the naming convention from cake of the primary key from the associated model.
Many thanks for your help & Greetings,
Guido
ps. i've changed the Model-Names of this post (if there is a type-mistake). So when i rename the primary keys of the associated tables, it all works fine, but i want them to name only to "id".
How about update your CommonType Model to this:
'CommonTypeDescription' => array(
'className' => 'CommonTypeDescription',
'foreignKey' => 'common_type_id', //or try type_description_id if there's an error
'dependent' => true
)
Then on your CommonTypeDescription model add this relationship, I think you forgot adding belongs to relationship to CommonType Model:
public $belongsTo = array(
'CommonType' => array(
'className' => 'CommonType ',
'foreignKey' => 'common_type_id',
));

CakePHP model linking, belongsTo, hasOne

I read the CakePHP book but couldn't make it.
I have a table named frendslists. Every user (owner_user_id) has too many friends and I add the friends to friend_id column. (Model name is Friendslist)
CREATE TABLE IF NOT EXISTS `friendslists` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`owner_user_id` int(20) unsigned NOT NULL,
`friend_id` int(20) NOT NULL COMMENT 'id of the friend',
PRIMARY KEY (`id`),
KEY `friend_id` (`friend_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
--id-------owner_user_id-----friend_id
--------------------------------------
--1--------1234--------------9200-----
--2--------1234--------------3210-----
--3--------1234--------------7600-----
I also have a profiles table. Every unique person have a profile there. One person can have only one profile. (Model name is Profile)
CREATE TABLE IF NOT EXISTS `profiles` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`profile_user_id` int(20) NOT NULL,
`name` varchar(50) NOT NULL,
`location` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
KEY `profile_user_id` (`profile_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
--id------profile_user_id---name------location-
-----------------------------------------------
--1-------9200--------------michael----usa-----
--2-------3210--------------john-------uk------
--3-------7600--------------danny------denmark-
I want to link friendslists table to profiles table. Is this one to one (hasOne) or many to one (belongsTo) type relationship ?
When I query friendslists table I want to get profiles data of the friends. What should I do inside CakePHP models and tables?
I created a foreign key like this:
ALTER TABLE `friendslists`
ADD CONSTRAINT `friendslists_ibfk_1`
FOREIGN KEY (`friend_id`)
REFERENCES `profiles` (`profile_user_id`)
ON DELETE CASCADE ON UPDATE CASCADE;
I changed model file to this:
class Friendslist extends AppModel {
var $name = 'Friendslist';
var $useTable = 'friendslists';
public $belongsTo = array(
'Profile' => array(
'className' => 'Profile',
'foreignKey' => 'friend_id'
)
)
function getAll(){
return $this->find('all');
}
}
At last when I do this:
$records=$this->Friendslist->find('all', array('conditions' => array(
'Friendslist.owner_user_id' => 1234)
));
I get these result:
[Friendslist] => Array
(
[id] => 1
[owner_user_id] => 1234
[friend_id] => 9200
)
[Profile] => Array
(
[id] =>
[profile_user_id] =>
[name] =>
[location] =>
)
)
I'm sure that profiles table has a record with profile_user_id=9200. But Profile records comes empty.
I'm a little confused why you're linking friendslists to profiles. Wouldn't it make more sense to link people with people and then get the profile therefrom?
In any case, what you're describing is a HasAndBelongsToMany(HABTM)
So in your Person model you want to specify that they have many other people (or in your case Profiles) that they're associated with and specify the lookup table.
Something like...
public $hasAndBelongsToMany = array(
'Person' => array(
'className' => 'Profile',
'joinTable' => 'friendslists',
'foreignKey' => 'owner_id',
'associationForeignKey' => 'friend_id'
)
);
And then within the friendslists model I'd describe it as a belongsTo listing both the owner and the profile.
Something like:
public $belongsTo = array(
'Person' => array(
'className' => 'Person'
,'foreignKey' => 'owner_user_id'
),
'Profile' => array(
'className' => 'Profile'
,'foreignKey' => 'friend_id'
)
);
You may need to tweak the names as I had a hard time digesting exactly what entities are at play, but that should give you an idea at least.

Translate from two tables with i18n database tables (cakePHP)

I have four tables:
gallery_categories table:
id (int);
title (varchar);
gallery_pictures table:
id (int);
title (varchar);
gallery_categories_gallery_pictures table to joint above tables:
gallery_category_id (int);
gallery_picture_id (int);
and the i18n table:
id (int)
locale (varchar)
model (varchar)
foreign_key (int)
field (varchar)
content (text)
I tried:
$this->GalleryCategory->bindModel(array(
'hasOne' => array(
'GalleryCategoriesGalleryPicture',
'GalleryPicture' => array(
'className' => 'GalleryPicture',
'foreignKey' => false,
'conditions' => array('GalleryPicture.id = GalleryCategoriesGalleryPicture.gallery_picture_id')
))));
$galleryCategories = $this->GalleryCategory->find('all', array(
'fields' => array('GalleryCategory.*','GalleryPicture.*')
));
But all time it returns with the right Category table fields and wrong Pictures table fields...
The Category fields contain the right translated words.
The Pictrures fields contain the wrong translated words.
The Models:
class GalleryCategory extends AppModel
{
public $tablePrefix = 'ef_';
var $name = 'GalleryCategory';
public $actsAs = array('Translate' => array(
'title' => 'titleTranslation'
)
);
}
class GalleryPicture extends AppModel
{
public $tablePrefix = 'ef_';
var $name = 'GalleryPicture';
public $actsAs = array('Translate' => array(
'title' => 'titleTranslation'
)
);
}
How could I get the right translated words from both table?
ps: The translation with "i18n Database Tables" works right with only one table (exp: only GalleryCategory or only GalleryPicture).
Translation doesn't work with associated models, see the last couple of lines here:
Note that only fields of the model you are directly doing find on will be translated. Models attached via associations won’t be translated because triggering callbacks on associated models is currently not supported.
Update
It might be tricky, as you have a HABTM relationship - previously I have worked around this by adding a second data retrieval to the afterFind callback of a model, but this was with a simpler association. Hope this helps.

how use table that association with itself?

how use table that association with itself ?
i use cakephp and table is Section :
create table SECTIONS
(
SECTIONID int(11) not null auto_increment,
TITLE char not null,
CONTROLID int(11) not null,
SECTIONPARENTID int(11),
primary key (SECTIONID)
)
this table have association with itself and i use belong to and has many association and my model is :
class Section extends AppModel {
var $name = 'Section';
var $primaryKey = 'SECTIONID';
var $displayField = 'TITLE';
}
i use belong to and has many association in two table. but i can't use in this example.
thanks for help.
Self referential models are simple in Cake once you know the trick, but you aren't doing yourself any favours by not using Cake naming conventions. I'll assume you're using a datasource that's out of your control :-)
Class Section extends AppModel {
var $belongsTo = array(
'Parent'=>array(
'className'=>'Section',
'foreignKey'=>'SECTIONPARENTID'
)
);
var $hasMany = array(
'Children'=>array(
'className'=>'Section',
'foreignKey'=>'SECTIONPARENTID'
)
);
}
When you run a query such as $this->Section->find('first') you'll get a returned array that looks like this:
section => array(
SECTIONID,
...
'Parent'=>array(
'SECTIONID',
....
),
'Children'=>array(
[0] => array(
[SECTIONID]
),
[1] => array(
[SECTIONID]
),
...
)
)

Resources