I need to join a model to itself... but I get the error "Not unique table/alias: 'Image'"
Image Schema:
id: int
thumbnail_image_id: int null
key: varchar... filename
location: varchar... s3 or local
created: datetime
modified: datetime
Image Model:
<?php
App::uses('AppModel', 'Model');
class Image extends AppModel {
public $belongsTo = array(
'Thumbnail' => array(
'className' => 'Image',
'foreignKey' => 'thumbnail_image_id'
)
);
public $hasOne = array(
'Thumbnail' => array(
'className' => 'Image',
'foreignKey' => 'thumbnail_image_id'
)
);
public function exampleFunction() {
return $this->find('all', array(
'contain' => array('Thumbnail')
));
}
Running exampleFunction it gives me the error "Not unique table/alias: 'Image'". CakePHP builds the SQL like this:
SELECT `Image`.`id`, `Thumbnail`.`id` FROM `images` AS `Image` LEFT JOIN `images` AS `Image`.`thumbnail_image_id` = `Thumbnail`.`id`;
but it should be something like this... right? (notice the inverted ON):
SELECT `Image`.`id`, `Thumbnail`.`id` FROM `images` AS `Image` LEFT JOIN `images` AS `Thumbnail`.`id` = `Image`.`thumbnail_image_id`;
If I run both SQL queries above in mysql console the second works.
Suggestions?
The problem is that you have used Thumbnail in both $belongsTo and $hasOne.
The Model will have no idea which association to use for the 'contain'.
Rename or remove one of your associations so they are unique.
Related
I have a few Tables/Models and I want to show the content of the models in one view.
My Schema:
My Models:
Adress:
var $name = "Adress";
public $belongsTo = array("Customer", "Country");
public $hasAndBelongsToMany = array(
'Contactperson' => array(
'className' => 'Contactperson'
)
);
ContactPerson:
var $name = "Contactperson";
public $hasAndBelongsToMany = array(
'Adress' => array(
'className' => 'Adress'
)
);
Country:
var $name = "Country";
public $hasMany = "Adress";
Customer:
var $name = "Customer";
public $hasMany = array(
'Adress' => array(
'className' => 'Adress',
'order' => array('Adress.mainadress DESC', 'Adress.created DESC')
)
);
My CustomerController:
$customer = $this->Customer->findByid($customerId);
$this->set('customer', $customer);
The return value is the content of the customer and the adress table but I want to get the content of every table.
I want to get a array with the content from customers, addresses, contactpeople and countries.
Thanks for helping.
Once you setup and linking each table correctly (with foreign key and db design), then you can retrieve all the related field easily with CakePHP.
Read up on CakePHP containable.
http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html
Recursive will also works, but higher recursive value can hurt your system if its getting too big.
I am in the FilesController and I'm trying to get a file based on the condition that its order belongs to the current user.
FilesController
// Check the file exists and that it belongs to the user
$this->File->find('first', array(
'conditions' => array(
'File.id' => $id,
'Order.Customer.id' => $this->Auth->user('id')
),
'recursive' => 2
));
Cake SQL Error
Unknown column 'Order.Customer.id' in 'where clause'
I'm trying to get the SQL to left join orders onto files and then left join customers onto orders, but I can't figure out how to join the customers table, although I'm sure I've done this before. I've tried everything I can think of with the conditions, and using contains.
Here's my model relationships:
Customer Model
class Customer extends AppModel {
public $hasMany = array('Order');
}
Order Model
class Order extends AppModel {
public $belongsTo = array('Customer');
public $hasMany = array('File');
}
File Model
class File extends AppModel {
public $belongsTo = array('Order');
}
Try joining the tables using the 'joins' parameter. Sometimes 'contains' doesn't work and you need to fall back on this.
$this->File->find('first', array(
'conditions' => array(
'File.id' => $id,
'Order.Customer_id' => $this->Auth->user('id')
),
'joins' => array(
array(
'table' => 'orders',
'alias' => 'Order',
'type' => 'LEFT',
'conditions' => array('File.orders_id = Order.id')
),
array(
'table' => 'customers',
'alias' => 'Customer',
'type' => 'LEFT',
'conditions' => array('Customer.orders_id = Order.id')
)
)
));
You may want to use Containable (http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html) as it is the easiest solution. You can not use Order.Customer.id as Cake does not nest conditions like that. Manual joins would also work.
$this->loadModel('Customer');
$customer = $this->Customer->findById($this->Auth->user('id'), array(
'conditions' => array(
'File.id' => $id
),
'recursive' => 2
));
Orders will be accessible as:
pr($customer['Order']);
File will be accessible as:
pr($customer['File']);
I realised there is no need to actually join the customers table in this instance, because the orders table already has the customer_id.
$this->File->find('first', array(
'conditions' => array(
'File.id' => $id,
'Order.customer_id' => $this->Auth->user('id')
)
));
I have a problem with my comments.
I have User model:
public $hasMany = array('Photo','Comment');
Comment model:
public $belongsTo = array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'user_id'
),
'Photo'=>array(
'className'=>'Photo',
'foreignKey'=>'photo_id'
)
);
and Photo Model
public $belongsTo = array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'user_id'
)
);
public $hasMany = array(
'Comment'=>array(
'className'=>'Comment',
'foreignKey'=>'photo_id'
)
);
When I read data of a photo I got:
'Photo' => array -> info about photo which is ok for me
'User' => array -> info about user ok for me
'Comment' => array -> all comments but only with id of users.
How can I connet comments with users to get username related with comment while retrieving data about photo?
You need to call $this->recursive = 2 before you call find(), that will fetch all associations of every object returned by your query. Alternatively you can set the $recursive variable inside any of your models.
The different types of recursion are as follows:
-1 Cake fetches Photo data only, no joins.
0 Cake fetches Photo data and its domain
1 Cake fetches a Photo, its domain and its associated Comments
2 Cake fetches a Photo, its domain, its associated Comments, and the
Comments’ associated Users
I also suggest considering Containable since you have complete control of all the data that is returned, down to specifying each field in any association
The photo model:
<?php
class Photo extends AppModel {
public $actsAs = array('Containable');
}
And your find method will look like this:
<?php
$this->Photo->find('all', array(
'contain' => array(
'User',
'Comment' => array(
'User' = array(
'fields' => array('username')
),
'conditions' => array(
'Comment.erased' => 0
)
))
'conditions' => array(
'Photo.id' => $id
)));
So I am using cakephp and I am a little new to this and I am facing certain issues.
1) I have two tables, report and issues.
cakephp:
report{id, type, details}
issue{id,report_id, details}
So now I am trying to get the report id in issues table. I have defined my hasmany and belongsto relationships as follows:
class Report extends AppModel {
var $name = 'Report';
var $hasMany = array(
'AtneIssue' => array(
'className' => 'Issue',
'foreignKey' => 'report_id',
'dependent' => true,
)
);
}
class Issue extends AppModel {
var $name = 'Issue';
var $belongsTo = array(
'Report' => array(
'className' => 'Report',
'foreignKey' => 'report_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
But this results in a sql error and the data not being saved to the table. I have set index to report_id to get id from Report.
Data is getting saved to reports but not to issues table.
Can someone tell me how to go about this?
Thanks in advance.
The first letter is replace by number here. dunno why... I figured how to post data But now I am not able to get the ID of the report and the data is getting corrupted like below:
Query: INSERT INTO `atne_issues` (`status`, `issue_owner`, `issue_reason`, `problem`) VALUES ('2nhold', '2ricsson', '2IQ - IP address incorrect', '2sdfasdf')
I'm building an MMA (mixed martial arts) website with CakePHP. I've got a fights table in my database that has three columns at its simplest: id, fighter_a, and fighter_b.
I'm having trouble getting my head around what type of relation my Fight model would have with my Fighter module. Am I right in thinking fighter_a and fighter_b would be two hasOne relations?
I tried this with the following in my Fight model:
<?php
class Fight extends AppModel {
public $name = 'Fight';
public $hasOne = array(
'FighterA' => array(
'className' => 'Fighter',
'foreignKey' => 'fighter_a'
),
'FighterB' => array(
'className' => 'Fighter',
'foreignKey' => 'fighter_b'
)
);
}
And then this in my Fighter model:
<?php
class Fighter extends AppModel {
public $name = 'Fighter';
public $hasMany = array(
'Fight'
);
}
But this threw an error in my CakePHP application when calling $this->Fight->findById($id) (where $id was the ID of a fighter):
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Fight.fighter_id' in 'field list'
How can I link my models so that I can call all fights a fighter has been in?
Distilled from conversation under the question, the solution would be this:
Rewrite the $hasMany in your FighterModel to look like:
public $hasMany = array(
'Fight' => array(
'className' => 'Fight',
'finderQuery' => 'SELECT * FROM fights AS Fight WHERE Fight.fighter_a_id = {$__cakeID__$} OR Fight.fighter_b_id = {$__cakeID__$};'
)
);