Database indexes cakePHP - mysql

I have two tables, namely 'Customer' and 'Event'. The relations between these two are as follows:
Event
var $belongsTo = array(
...
'Customer'=>array(
'className' => 'Customer',
'foreignKey' => 'customer_id'
)
);
Customer
var $hasMany = array(
'Event' => array(
'className' => 'Event',
'foreignKey' => 'customer_id',
'dependent' => false,
)
);
Each and every customer record holds a company id as well as currently logged in user. What I would like to achieve is to get all of the events for a day, related only to a particular company, but that is of course not working since the event table does not hold company id. Maybe the following find call will help to understand the issue better:
$conditions = array('company_id'=>CakeSession::read("Auth.User.company_id"), 'date'=>date("Y-m-d", $tomorrow));
$tomorrowsEvents = $this->find('all', array(
'conditions'=>$conditions, 'contain'=>array('User', 'Customer')));
Moreover, a customer belongs to a company and a company has many customers, just as follows:
Customer
var $belongsTo = array(
'Company' => array(
'className' => 'Company',
'foreignKey' => 'company_id',
'dependent' => false,
),
);
Company
var $hasMany = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'company_id',
'dependent' => false
),
'Customer'=>array(
'className' => 'Customer',
'foreignKey' => 'company_id',
'dependent' => false
)
);
Any help is much appreciated.

I would actually do this query "backwards" by doing it from Customer, and using the containable behavior to contain the related Events:
$this->Customer->find('all',
array(
'conditions' => array(
'company_id' => CakeSession::read("Auth.User.company_id")
),
'contain' => array(
'Event' => array(
'conditions' => array(
'Event.date' => date("Y-m-d", $tomorrow)
)
)
)
));

In your case it seems that Events have many companies and companies have many events. This is ideal situation for hasAndBelongsToMany relationship. However, you have to focus on the className and joinTable properties to handle the non convenient naming of the join table customers.
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasandbelongstomany-habtm

you need to rethink the problem, because a user can be (customer or company) then they have a group or they are in a type of user. then a user belongs to a group or user type, this group can be a client or company .
users belongsto a group
group has many user
users hasmany events
events has many users
You can tell if is customer or company is the type of group that owns
table___group
id ____ category ____ subcategory
1 ____ customer ____ example
2 ____ company ____ example

Related

Retrieving Data From two tables that are associated with a forign key in CakePhp

I have two tables named login and userDetail
Login
login_id
uname
pswd
userdetail_id
and
userdetails
userdetail_id
name
address
email
the login table contain userdetails_id in the userDetail table. i want to get all data from Login table and userDetail table and save it to a variable
if anyone knows, please answer me......
First of all your table structure must be as below.
logins Table.
Id auto_increment
username
password
userDetails Table.
Id auto_increment
user_id
name
address
etc...
Now model for each table would be.
Login
<?php
class Login extends AppModel
{
var $name = 'User';
var $hasMany = array
(
'UserDetail' => array
(
'className' => 'UserDetail',
'foreignKey' => 'user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
}
?>
UserDetail
<?php
class UserDetail extends AppModel
{
var $name = 'UserDetail';
var $belongsTo = array
(
'User' => array
(
'className' => 'User',
'foreignKey' => 'user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => ''
)
}
?>
And finally in controller where you need to fetch login detail.
$login_detail = $this->Login->find('all');
You will see userDetail table records in resulting $login_detail.
use pr($login_detail); in controller to see it in action.
Cheers.
Feel Free to ask.
Make sure ContainableBehavior has been enabled. After that you can use following query:
$login = $this->Login->find('first', array(
'contain' => array(
'Userdetail.userdetail_id'
'Userdetail.name',
'Userdetail.address',
'Userdetail.email'
),
'fields' => array(
'Login.login_id'
'Login.uname',
'Login.pswd'
),
'conditions' => array(
'Login.login_id' => 1
)
));
The query for this task would be:
SELECT Login.*, name,address,email
FROM Login JOIN userdetails
ON Login.userdetail_id=userdetails.userdetail_id
The results of this query could be saved to variables by looping in cakephp.

Model association is off for joining users table on comments table for a submission

My associations in CakePHP are a bit off. Here is the problem. I have a users table
and a comments table. When retrieving a submission I want to join the users table
on the comments table with Comment.user_id == User.id.
Comment Model:
class Comment extends AppModel {
var $name = 'Comment';
var $belongsTo = array('User');
var $hasMany = array(
'CommentsLike' => array(
'className' => 'CommentsLike'
),
'Comment' => array(
'className' => 'Comment'
)
);
var $hasAndBelongsToMany = array(
'User' => array(
'className' => 'User',
'joinTable' => 'comments',
'foreignKey' => 'Comment.user_id',
'associationForeignKey' => 'user_id'
),
'Submission' => array(
'className' => 'Submission'
)
);
User Model:
class User extends AppModel {
var $name = 'User';
var $hasMany = array('Comment');
var $hasAndBelongsToMany = array(
'Comment' => array(
'className' => 'Comment',
'joinTable' => 'comments',
'foreignKey' => 'Comment.user_id',
'associationForeignKey' => 'user_id',
),
'Submission' => array(
'className' => 'Submission',
'order' => 'Submission.created DESC'
)
);
When I grab a submission, it grabs all comments for it, but it doesn't join on
the users table which is what I want
Submission Model:
class Submission extends AppModel {
var $name = 'Submission';
var $belongsTo = array(
'User' => array(
'className' => 'User'
)
);
var $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'order' => 'Comment.created DESC',
'conditions' => array(
'Comment.deleted' => 0
)
),
'SubmissionsVote' => array(
'className' => 'SubmissionsVote'
),
'SubmissionThumbnails' => array(
'className' => 'SubmissionThumbnails'
)
);
A find on a submission will return this:
[Submission] => Array
(
// removed for sake of stackoverflow length
)
[User] => Array
(
[id] => 2
[username] => bob_cobb
)
[Comment] => Array
(
[0] => Array
(
[id] => 1
[submission_id] => 112
[comment] => this is a test comment
[user_id] => 2
[created] => 5 minutes ago
[deleted] =>
[parent_id] =>
)
)
As you can see [Comment][0] should also have [Comment][0][User] or something similar.
Why would I want this? Simple: I want to grab the username of the person who
commented by the foreign key of user_id from the comments table. I've read the docs and tutorials and pretty sure I'm close on this but not sure what's holding me back.
Here is a screenshot of the comments table:
Here is a screenshot of the users table structure:
You can a couple of options:
Either set the recursive property in the Submission model to the level you need to fetch back your associated data ( see http://book.cakephp.org/2.0/en/models/model-attributes.html#recursive )
or (more preferable) use the Containable behaviour ( see http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html ) to specify what related data to return:
class Submission extends AppModel
public $actsAs = array('Containable');
}
Use it like this in your find:
$data = $this->Submission->find('all', array(
'conditions'=>array(your conditions here),
'contain'=>array(
'User,
'Comment'=>array(
'User'
)
)
));
Most people use containable in every model so add it to AppModel and set AppModel::recursive to -1

Cakephp model with conditions

Is it possible to make relation in cakephp model with some specific conditions:
eg:
var $belongsTo = array(
'Parent' => array(
'className' => 'Category',
'foreignKey' => 'parent_id',
'dependent' => true
)
);
I want the above relation on where field parent_id is not 0. Please give some overview on How to do that?
You can put conditions in the relations just like you do with finds.
var $belongsTo = array(
'Parent' => array(
'className' => 'Category',
'foreignKey' => 'parent_id',
'dependent' => true,
'conditions' => array(
...
)
)
);

Multiple relations to the same model CakePHP

Hey we have three tables in our database which are connected through two relationships which are Account and Invoices.
Accounts (id....)
Invoices (id, sender_id, receiver_id)
Relationships (id, sender_id, receiver_id)
Sender and receiver are both foreign keys which reference the account table so in cakePHP an account_id. The relationship table specifies relationships where invoices can be sent or received and the invoice table displays the invoices that have been sent.
How do we link both these foreign keys with Accounts in CakePHP?
Cake is finding there is a relationship and listing the receivers available to send an invoice to. At the moment its sending the right sender_id to the database but the sending the relationship_id to the database as the receiver_id in the invoice table.
Already gone through this but doesnt work: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasandbelongstomany-habtm
Here is what we have for our two models:
Account model:
class Account extends AppModel{
var $name='Account';
public $useTable = 'accounts';
public $primaryKey = 'id';
var $hasAndBelongsToMany = array(
'User' =>
array(
'className'=>'User',
)
);
var $hasMany = array(
'Template' =>
array(
'className'=>'Template',
'foreignKey'=>'account_id',
),
'InvoiceRecieved' => array(
'className'=>'Invoice',
'foreignKey'=>'receiver_id',
),
'InvoiceSent' => array(
'className'=>'Invoice',
'foreignKey'=>'sender_id',
)
);
}
Invoice model:
class Invoice extends AppModel{
var $name='Invoice';
var $hasAndBelongsToMany = array(
'Field' =>
array(
'className'=>'Field',
'joinTable'=>'fields_invoices'
)
);
var $belongsTo = array(
'Sender' => array(
'className' => 'Account',
'foreignKey' =>'account_id',
),
'Receiver' => array(
'className' => 'Account',
'foreignKey' =>'receiver_id',
)
);
public $useTable='invoices';
public $primaryKey='id';
Invoice Controller:
$accounts2=$this->User->AccountsUser->find('list', array(
'fields'=>array('account_id'),'conditions' => array(
'user_id' => $this->Auth->user('id'))));
$accounts=$this->User->Relationship->find('list', array('fields'=>array('receiver_id'),'conditions' => array('sender_id' => $accounts2)));
if($this->request->is('post')){
($this->Invoice->set($this->request->data));
//if($this->Invoice->validates(array('fieldList'=>array('receiver_id','Invoice.relationshipExists')))){
$this->Invoice->save($this->request->data);
$this->Session->setFlash('The invoice has been saved');
}else {
$this->Session->setFlash('The invoice could not be saved. Please, try again.');
}
//}
$this->set('accounts', $accounts);
$this->set('accounts2', $accounts2);
Add view:
<?php
echo $this->Form->create('Invoice', array('action'=>'addinvoice'));
echo $this->Form->input('sender_id',array('label'=>'Sender: ', 'type' => 'select', 'options' => $accounts3));
echo $this->Form->input('receiver_id',array('label'=>'Receiver: ', 'type' => 'select', 'options' => $accounts));
echo $this->Form->end('Click here to submit Invoice');
?>
I don't think you need a join table for invoices, and senders and receivers. You can store these foreign keys in your invoices table. Your relationships would then be:
<?php
class Invoice extends AppModel {
public $belongsTo = array(
'Sender' => array(
'className' => 'Account',
'foreignKey' => 'sender_id'
),
'Receiver' => array(
'className' => 'Account',
'foreignKey' => 'receiver_id'
)
);
}
If you then need to distinguish invoices that have been sent or not, you could also add a column called status_id or similar, and store another foreign key to a new statuses table, with an ID column and name column, and the following sample data:
id name
== ====
1 Draft
2 Sent
And any other statuses you may need.

How to make a variable relationship?

Each Comment can be the child of either a Question, a Game, or a User. I designed the table so that it has two fields to manage the relationship, parent_type and parent_id. I do not understand how I would make this relationship work with CakePHP 2.1.. I know it is a belongsTo relationship, but how would I specify the table to which it belongs based on another field in that table?
Comments model
var $belongsTo = array(
'Question' => array('className' => 'Question', 'foreignKey' => 'id'),
'Game' => array('className' => 'Game', 'foreignKey' => 'id'),
'User' => array('className' => 'User', 'foreignKey' => 'id'));
Questions model
var $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'parent_id',
'conditions' => array('Comment.parent_type' => 'question')
)
);
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html