I have been trying to define database relations and constraints in both model and Database?
Currently it is throwing error.
I have two tables 'posts' and 'comments'. And I have defined the relationship in my models as follows:
class Comment extends AppModel {
public $belongsTo = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'post_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
and
class Post extends AppModel {
public $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'post_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
Am I missing something ? Anyone please help.
Thanks in Advance..
I don't think you need all those empty values and they may be messing things up. You should only need:
Comment.php
class Comment extends AppModel {
public $belongsTo = array(
'Post'
);
}
and
class Post extends AppModel {
public $hasMany = array(
'Comment'
);
}
Also, let us know the error as currently we have nothing to go on...
Related
I need to get data(all the id of the assurance that related to that Indicator datum) from assurances_indicator_data,and I didn't know the right way to join data in CakePHP my code didn't work and it return an empty array.
IndicatorDatum Model :
public $hasAndBelongsToMany = array(
'Assurance' => array(
'className' => 'Assurance',
'joinTable' => 'assurances_indicator_data',
'foreignKey' => 'indicator_datum_id',
'associationForeignKey' => 'assurance_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
function getIndicatorDataAssurance($indi_id){
$assuranceData = $this->find('all',array(
'joins' => array(
array('table' => 'assurances_indicator_data',
'type' => 'INNER',
'conditions' => array(
'AssurancesIndicatorData.indicator_datum_id' => $cun_indi)))));
return $assuranceData;
}
}
The easiest way to join tables in CakePhp is to have to models each representing a table in your database.
An example below, you can modify it to the names of your tables and models:
class ModelOne extends AppModel{
public $belongTo = array('ModelTwo');
}
class ModelTwo extends AppModel{
public $hasMany = array('ModelOne');
}
Then in your controller if you query any of these models, your response array should contain data from both tables.
greatings!
my models are not being configured as containable. this following query dont display the correct result (i want to retrieve all the available cars between two dates in all category)
$car=$this->Genre->find('all', array(
'contain' => array(
'cars'=>array(
'conditions'=>array(
'cars.startdate <=' => $qdu ,
'cars.enddate >=' => $qau
)
)
)
)
);
this is my Genre model:
class Genre extends AppModel {
public $actsAs = array('Containable');
public $belongsTo = array(
'houses' => array(
'className' => 'houses',
'foreignKey' => 'houses_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
public $hasMany = array(
'cars' => array(
'className' => 'cars',
'foreignKey' => 'genres_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
and this is car model:
class Car extends AppModel {
public $belongsTo = array(
'Genres' => array(
'className' => 'Genres',
'foreignKey' => 'genres_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
public $hasMany = array(
'ways' => array(
'className' => 'ways',
'foreignKey' => 'cars_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
Model names should normally be singular, so "Car" instead of "cars".
$car=$this->Genre->find('all', array(
'contain' => array(
'Car'=>array(
'conditions'=>array(
'Car.startdate <=' => $qdu ,
'Car.enddate >=' => $qau
)
)
)
)
);
Also, make sure the Genre model loads the Containable behaviour.
class Genre extends AppModel {
$actsAs = array('Containable');
}
Associations should also use singular, capitalised model names:
class Genre extends AppModel {
public $actsAs = array('Containable');
public $belongsTo = array(
'House' => array(
'className' => 'House',
'foreignKey' => 'houses_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
public $hasMany = array(
'Car' => array(
'className' => 'Car',
'foreignKey' => 'genres_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
It's a Cake convention to have pluralised controllers (CarsController, GenresController) and singular models (Car, Genre). When defining associations you're in essence linking models together and not controllers, hence the need for singular, capitalised classnames.
I have 2 models Profiles and Messages. When i try to get all messages in its controller, cake doesn`t return any profiles in result array.
In Message controller:
$this->Message->recursive=3;
$m=$this->Message->find('all');
Models:
class Message extends AppModel {
var $name = 'Message';
var $primaryKey = 'id';
var $useTable = 'messages';
var $belongsTo = array(
'Profile' => array(
'className' => 'Profile',
'foreignKey' => 'author_id',
'conditions' => '',
'fields' => '',
'order' => ''
));
And
class Profile extends AppModel {
var $name = 'Profile';
var $primaryKey = 'id';
var $useTable = 'profiles';
var $belongsTo = array(
'Account' => array(
'className' => 'Account',
'foreignKey' => 'account_id',
'conditions' => '',
'fields' => '',
'order' => ''
));
var $hasMany = array(
'Message' => array(
'className' => 'Message',
'foreignKey' => 'Author_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
));
P.S. I cant wait 7 hours for answer option.
I found solution eventually, my Message model filename was messageS.php, as soon as i renamed it to message.php, got everything i needed. I it helps someone
Per your answer, (but also relevant to other people), if you're pretty sure your associations are correct, the next step is to check your filenames to make sure they fit the conventions (singular model).
Another note, if you're using recursive 3, (wasn't aware it went higher than 2, but apparently it does), you're probably better off using CakePHP's Containable Behavior. Even using recursive of 2 is usually excessive.
write in Message.php model file:
var $belongsTo = array(
'Profile' => array(
'className' => 'Profile',
'foreignKey' => 'author_id',
'conditions' => '',
'fields' => '',
'order' => ''
));
write in Profile.php model file:
var $hasMany = array(
'Message' => array(
'className' => 'Message',
'foreignKey' => 'Author_id', // Hear you "Author_id" should change as "author_id"
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
));
Controller:
$m=$this->Message->find('all');
Now its working fine...Enjoy..
I would like to use hasMany through relationship to connect two users through a model invitations
I currently have the following controller:
class User extends AppModel {
var $name = 'User';
var $displayField = 'username';
var $hasMany = array(
'Invitation' => array(
'className' => 'Invitation',
'foreignKey' => 'sender_user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
'Invitation' => array(
'className' => 'Invitation',
'foreignKey' => 'receiver_user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
)
}
However, when i get error:
Error: Database table sender_users for model SenderUser was not found.
Which is a bit annoying, because I already thought I specified that I want to use Invitation.
What is the issue, what code do I change?
First: you can't create the same association twice. Even from a PHP syntax perspective that's not possible. You'll have to give each association a unique name:
public $hasMany = array(
'SentInvitation' => array(...),
'ReceivedInvitation' => array(...)
);
Second, the problem is probably that you don't have an Invitation model. Cake creates a model on-the-fly according to naming conventions. Since you have a column sender_user_id, according to naming conventions you should therefore also have a sender_users table. Create the Invitation model and set it up without that association, then Cake shouldn't be looking for it.
Another noob question - using v1.2.1.8004 of CakePHP, I think...
I have 3 tables, broker (B), quote_site (QS) and broker_quote_site (BQS) that links them together.
B has many BQS (it belongs to B)
QS has many BQS (it belongs to QS)
I am trying to retrieve quote sites, that are linked to a specific broker, but CakePHP is not doing the joins to the tables behind the scenes.
Here is my query:
$quote_sites = $this->QuoteSite->find('all', array(
'conditions' => array(
'Broker.company_id' => $company_id,
'BrokerQuoteSite.is_active' => true
),
'contain' => array(
'BrokerQuoteSite' => array(
'Broker'
)
)
));
Here are the related models:
<?php
class QuoteSite extends AppModel
{
var $name = 'QuoteSite';
//$validate set in __construct for multi-language support
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $hasMany = array(
'BrokerQuoteSite' => array(
'className' => 'BrokerQuoteSite',
'foreignKey' => 'quote_site_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
?>
Broker:
<?php
class Broker extends AppModel
{
var $name = 'Broker';
//$validate set in __construct for multi-language support
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $hasMany = array(
'BrokerQuoteSite' => array(
'className' => 'BrokerQuoteSite',
'foreignKey' => 'broker_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
?>
And the last one:
<?php
class BrokerQuoteSite extends AppModel
{
var $name = 'BrokerQuoteSite';
//$validate set in __construct for multi-language support
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $belongsTo = array(
'Broker' => array(
'className' => 'Broker',
'foreignKey' => 'broker_id',
'conditions' => '',
'fields' => '',
'order' => '',
) ,
'QuoteSite' => array(
'className' => 'QuoteSite',
'foreignKey' => 'quote_site_id',
'conditions' => '',
'fields' => '',
'order' => '',
)
);
}
?>
Thanks in advance for any tips/tricks.
Chris why don't you define Broker as a HABTM relationship then a simple find will retrive the desired results?
class Broker extends AppModel {
var $name = 'Broker';
var $hasAndBelongsToMany = array(
'QuoteSite' =>
array(
'className' => 'QuoteSite',
'joinTable' => 'broker_quote_sites',
'foreignKey' => 'broker_id',
'associationForeignKey' => 'quote_site_id'
)
);
}
http://book.cakephp.org/view/1044/hasAndBelongsToMany-HABTM
Nice question and what I thought is to make it two steps
$this->Broke = ClassRegistry::init("Broke");
$brokeids = $this->Broke->find("list",array("conditions"=>array('Broker.company_id' => $company_id))); //get all B ids
$this->QuoteSite->Behaviors->attach('Containable'); //use containable behavior
$quote_sites = $this->QuoteSite->find('all',array(
'contain'=>array(
'BrokerQuoteSite'=>array(
'conditions'=>array(
"BrokerQuoteSite.broke_id"=>$brokeids,
"BrokerQuoteSite.is_active" => true
)
)
)
)
);
The code is NOT tested yet,maybe some syntax mistakes out there.Hope it helps.
update
$this->Broke = ClassRegistry::init("Broke");
$this->Broke->recursive=2;
$brokes = $this->Broke->find("all",array("conditions"=>array("Broke.company_id"=>$comany_id)));
the QS information you need shall be found if you view the result with debug($brokes); .What you need to do is extracting them from the array.
Cheers.