Relationships not working correctly - cakePHP - cakephp

I have relationships set up by the built in CakePHP build function. First, my tables:
assets
id | company_id | group_id | location_id | item_id | invoice_id | item_number | description | purchase_value | purchase_date | barcode | colour | picture | created | modified
repairs
id | company_id | asset_id | invoice_id | created | modified
My relationship in my asset model looks like this:
public $hasMany = array(
'Repair' => array(
'className' => 'Repair',
'foreignKey' => 'asset_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
And in my repair model, like this:
public $belongsTo = array(
'Asset' => array(
'className' => 'Asset',
'foreignKey' => 'asset_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
However, when I try to view an asset, it shows this error:
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Asset.asset_id' in 'field list'
SQL Query: SELECT `Asset`.`id`, `Asset`.`company_id`, `Asset`.`group_id`, `Asset`.`location_id`, `Asset`.`item_id`, `Asset`.`invoice_id`, `Asset`.`item_number`, `Asset`.`description`, `Asset`.`purchase_value`, `Asset`.`purchase_date`, `Asset`.`barcode`, `Asset`.`colour`, `Asset`.`picture`, `Asset`.`created`, `Asset`.`modified`, `Asset`.`asset_id` FROM `asset_register`.`assets` AS `Asset` WHERE `Asset`.`company_id` = 1 AND `Asset`.`asset_id` = (4)
Anyone know what the issue is?
EDIT TO UPDATE
My find statement is the plain CakePHP find statement.
$options = array('conditions' => array('Asset.' . $this->Asset->primaryKey => $id));
$this->Asset->recursive = 1;
$this->set('asset', $this->Asset->find('first', $options));

EDIT
Add this line to your asset model
public $primaryKey = 'id';
and make sure that $primaryKey is not defined somewhere else in the model.

Related

How get data from Relationship tables

I have 2 table in my database that second(orders) table has foreign_key of primary key of first(books) table like these
Books
----+---------+-------------
id | slug | name |
----+---------+--------------
1 | math | mathematics |
----+---------+--------------
2 | physics | holidays |
-----------------------------
Orders
----+---------+-------+--------
id | book_id | count | price |
----+---------+-------+--------
1 | 2 | 12 | 100000 |
--------------------------------
I want result like below
result
----+---------+----------+----------+----------+------------------
id | book_id | slug | name | order_id | count | price |
----+---------+----------+----------+-----------------------------
1 | 2 | physics | holidays | 1 | 12 | 100000 |
------------------------------------------------------------------
I believe each product has a price. To that start with relating PRODUCT table to PRICE.
In cake this is done very easily:
in your Model (Product.php)
class Product extends AppModel{
public $hasMany = array('Price');
}
in Price.php
class Price extends AppModel{
public $hasBelongTo = array('Product');
}
in your controller if you query any of these Models the returned array will contain data from both models.
make the relationships as follow
Product.php
....
public $hasMany = array(
'Price' => array(
'className' => 'Price',
'foreignKey' => 'product_id',
'dependent' => true,
'conditions' => '',
'group' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
....
Price.php
.....
public $belongsTo = array(
'Product' => array(
'className' => 'Product',
'foreignKey' => 'product_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
....
then in your controller use this query
$this->Product->find('all',array('contain'=>array('Price')));

Retrieving related model's data CakePHP

Here is the database tables in question:
Companies:
____________________
| id | name |
____________________
| 1| Unimex|
| 2| Solomex|
Users:
________________________
| id | name | company_id
_________________________
| 1| John | 1
| 2| Ricky| 2
Events:
_____________________________________
| id | user_id | details | date|
_____________________________________
| 1| 1| null | 2014-04-01
| 2| 1| null | 2014-04-15
| 3| 2| null | 2013-04-01
| 4| 1| null | 2014-04-02
What I would like to do is to retrieve a list of users(based on company's id) and their related events for a range of dates. What I have tried to do is the following:
$users = $this->User->find('all',
array(
'conditions' => array(
'company_id' => CakeSession::read("Auth.User.company_id")
),
'contain' => array(
'Event' => array(
'conditions' => array(
'Event.date >=' => $from,
'Event.date <=' => $to
)
)
)
)
);
This way I get the list of Users with their related events, but the $from and $to dates are not taken into consideration, meaning all of the events for a particular user are returned.
The relations are like following:
Event:
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
));
User:
var $hasMany = array(
'Event' => array(
'className' => 'Event',
'foreignKey' => 'user_id',
'dependent' => false,
)
);
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
));
Any help or guidance is much appreciated.
Following are the two queries that are executed by cakePHP:
SELECT `User`.`id`, `User`.`company_id`, `User`.`name`, `User`.`surname`, `User`.`email`, `User`.`phone`, `Company`.`id`, `Company`.`name`, `Company`.`address` FROM `database`.`users` AS `User` LEFT JOIN `database`.`companies` AS `Company` ON (`User`.`company_id` = `Company`.`id`) WHERE `company_id` = 54
SELECT `Event`.`id`, `Event`.`customer_id`, `Event`.`user_id`,`Event`.`details`, `Event`.`hours`, `Event`.`minutes`, `Event`.`xhours`, `Event`.`xminutes`, `Event`.`assignment`, `Event`.`start_time` FROM `database`.`events` AS `Event` WHERE `Event`.`user_id` IN (124, 125, 126, 141, 143, 144, 147, 156)
So as you can see the date in the Event field conditions is not taken into consideration. If there is any other important information that I can provide, please, just let me know.
Moreover, I have just tried to retrieve only specific fields of the Event model, and that did not work as well. So basically the model is just contained as is, an no other parameter is applied.
Or maybe the model is not contained at all and the result I get is only because of the recursive being set to 1?
I don't see the error only as a suggestion
$users = $this->User->find('all',
array(
'contain' => array(
'Event' => array(
'conditions' => array(
'and' => array(
array(
'Event.date >=' => $from,
'Event.date <=' => $to
),
'company_id' => CakeSession::read("Auth.User.company_id")
)
)
)
)
)
);
The problem is that there was a typo. I always thought it has to be:
var $actAs = array('Containable');
But it actually had to be $actsAs.

Retrieving related model's data in CakePHP

Here is the database tables in question:
Companies:
____________________
| id | name |
____________________
| 1| Unimex|
| 2| Solomex|
Users:
________________________
| id | name | company_id
_________________________
| 1| John | 1
| 2| Ricky| 2
Events:
_____________________________________
| id | user_id | details | date|
_____________________________________
| 1| 1| null | 2014-04-01
| 2| 1| null | 2014-04-15
| 3| 2| null | 2013-04-01
What I would like to do is to retrieve events for a particular date based on company's id. What I have tried to do is the following:
$this->User->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)
)
)
)
));
but this retrieves all of the events for the company, the date condition is not being applied.
In the best case I would like to retrieve only the events for one company for a particular date. Otherwise I would get by with returning a list of users related to one company and their events for that particular date.
What would be the most efficient way to do this?
Any help or guidance is much appreciated.
Following are the relations between the tables:
Events:
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
));
Users:
var $belongsTo = array(
'Company' => array(
'className' => 'Company',
'foreignKey' => 'company_id',
'dependent' => false,
),
);
Here is the query that I get:
SELECT Event.id, Event.customer_id, Event.user_id, Event.project_id, Event.service_id, Event.date, Event.start_city, Event.material, Service.id, Service.company_id, Service.name, Service.service_nr, User.id, User.company_id, User.employee_nr, User.name, User.surname, User.email, User.password, User.role, Customer.id, Customer.company_id, Project.name, Project.description, Project.link_nr, Project.start_date, Project.finish_date, Project.project_nr FROM schedule.events AS Event LEFT JOIN schedule.services AS Service ON (Event.service_id = Service.id) LEFT JOIN schedule.users AS User ON (Event.user_id = User.id) LEFT JOIN schedule.customers AS Customer ON (Event.customer_id = Customer.id) LEFT JOIN schedule.projects AS Project ON (Event.Project_id = Project.id) WHERE 1 = 1
The problem right now is that the company id is not taken into concideration, and all of the events are being returned no matter what date it is.
I’ve tried this solution and it works for me.
I made all tables with small letters according to cake conventions like companies, events and users.
This is Event Model
class Event extends AppModel {
var $actsAs = array('Containable');
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
This is controller Event class
$tomorrow = '2013-04-01';
$this->Event->find('all',
array(
'conditions' => array(
'date' => date("Y-m-d", strtotime($tomorrow)),
),
'contain' => array(
'User' => array(
'conditions' => array(
'User.company_id' => CakeSession::read ('Auth.User.company_id')
)
)
)
));
This will give you
SELECT `Event`.`id`, `Event`.`user_id`, `Event`.`details`, `Event`.`date`, `User`.`id`, `User`.`name`, `User`.`company_id`
FROM `schedule`.`events` AS `Event`
LEFT JOIN `schedule`.`users` AS `User` ON (`Event`.`user_id` = `User`.`id` AND `User`.`company_id` = 2)
WHERE `date` = '2013-04-01'
I hope this will work for you. Thanks
try this code:
$this->Event->find('all',
array(
'conditions' => array(
'User.company_id' => CakeSession::read("Auth.User.company_id"),
'Event.date' => date("Y-m-d", $tomorrow)
),
'contain' => array('User')
));

Cakephp relation modes

public $belongsTo = array(
'Hospital' => array(
'className' => 'Hospital',
'foreignKey' => 'hospital_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
public $hasMany = array(
'Floor' => array(
'className' => 'Floor',
'foreignKey' => 'hospital_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
i have two tables hospitals and floors, i have retrieve data from hospital table and show in floor views in add floor.
You have already set up the relationship, so now you just need to create a controller action and a view.
Assuming your tables are in place, the easiest way to do this would simply be to run cake bake all on the Hospital model and Cake will generate the views for you. Cake is intelligent enough to generate a view that will show you a list of associated floors if that is what you want (it was unclear from your post).
You can retrieve the data from database like this...
mysql_select_db("users"); //your database name
$sql = mysql_query("SELECT * FROM langs"); //table name
$limit = 4;
$count = 3;
echo "<table border='1'>";
while($row = mysql_fetch_array($sql)){
$name=$row['name'];
$email=$row['email'];
$contact=$row['contact'];
if($count < $limit){
echo "<tr>";
}
............. //you can put in table and in any other field
?>

Joins tables in Cakephp

i have a two tables namely; histories and users. i need to display data like:
id | Username | Lastest created Post | First created Post
the data of id and username is from users table and the last created and first created post data is from histories. i need to view all the users, their lastest created post and their first created post. please help me to make controller and view thanks
Try below.
<?php
$users = $this->User->find('all',array
(
'conditions' => array
(
//conditions goes here
),
'fields' => array
(
'User.id',
'User.username',
'History.Lastest created Post',
'History.First created Post'
)
));
?>
Assume that relation between 'User' and 'History' table is One-to-One and there's a 'user_id' column in History table, you may need to specify relation between them in History model, for example:
var $hasOne = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
Then, you need to perform joins to do this. For example, somewhere in your User model, try something like this:
class User extends AppModel {
....
function getAllUsersHistory{
$allHistories = $this->find('all', array(
'joins' => array(
'table' => 'history',
'alias' => 'HistoryJoin'
'type' => 'INNER',
'conditions' => array(
// your conditions, for example: 'History.user_id' => 'User.id'
)
),
'fields' => array(
'User.id',
'User.username',
'History.lastest_created_post',
'History.first_created_post'
)
));
return $allHistories;
}
.....
}

Resources