Another "need to pull data from two tables in cakephp" - mysql

Ok, I have two tables, users and units. 'Unit' belongsTo 'User', and 'User' hasMany 'Unit'. I would like to access all of the data from my units table, and append SOME of the data from my users table for the view. Here is my controller code:
public function condos() {
$u=$this->User->Unit->find('all', array('conditions'=>array('type'=>'condo', 'active'=>1)));
$this->set('allcondos', $u);
}
I have two models, User and Unit, here is the code for them:
from unit.php:
class Unit extends AppModel {
var $name='Unit';
var $belongsTo=array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'user_id'
) );
}
and from user.php:
class User extends AppModel {
var $name='User';
var $hasMany=array(
'Unit'=>array(
'className'=>'Unit',
'foreignKey'=>'user_id'
) );
}
Here is my view code:
<?php foreach ($allcondos as $condo) { ?>
<section class="listings">
<figure>
<img src="<?php echo $condo['Unit']['photo1']; ?>" />
</figure>
<h1><?php echo $condo['Unit']['complex'], ' ', $condo['Unit']['unitnum']; ?></h1>
<h2><?php echo $condo['Unit']['city']; ?>, <?php echo $condo['Unit']['state']; ?> | (<?php echo $condo['User']['area_code']; ?>)<?php echo $condo['User']['exchange'];?>-<?php echo $condo['User']['sln'];?></h2>
<p><?php echo $condo['Unit']['unit_desc']; ?></p>
</section>
<?php } ?>
I have a problem with the call to $condo['User']['any_field'] as it returns zero 'User' data. (It returns the 'Unit' data just fine). I don't know how to access both tables, obviously.
If I debug $allcondos in the view, it looks like this:
Array
(
[0] => Array
(
[Unit] => Array
(
[id] => 1
[user_id] => caribeincrentals
[additional fields] ...
)
[User] => Array
(
[id] =>
[user_id] =>
[additional fields] ...
)
)
[1] => Array ...
)

$this->Unit->find('all', array(
'conditions' => array(
'type' => 'condo',
'active' => 1,
),
'contain' => array(
'User',
),
));
Use containable to get related data. You can use conditions within that contain as well to restrict what information you want.
http://book.cakephp.org/view/1323/Containable

Without your database details, it is tough to say exactly what is going on. However, you seem to be using a string value as the foreignKey that links your 2 models together. This is a bad idea.
I suggest changing the user_id fk to an int datatype that references the id key column on the Users table (well, assuming that id is an autoincrementing integer value).
It's tough to say if this is the exact problem, but it's definitely worth checking out and will help you avoid some other headaches in the future.
UPDATE
If you structure your tables according to Cake conventions, most of the associative work will be done for you. Here's how I would do it:
Users table ('users'):
id primary key (int)
User model:
$hasMany = array( 'Unit' );
Units table ('units'):
id primary key (int)
user_id corresponds to id in users table
Unit model:
$belongsTo = array( 'User' );
If you set your tables & models up like that, Cake will automatically associate 'user_id' in the units table with 'id' in the users table.

Related

Codeigniter: Know AI ID of query

When a user create an item, on my controller i need to send 2 SQL Query.
The first is easy to do:
$data = array(
'author' => $this->input->post('author'),
'name' => $this->input->post('name'),
);
$this->item_model->insertItem($data);
But on my second query, i need to recover, to find the ID of the query showing just before.
For example:
$data = array(
'user_id' => $_SESSION['user_id'],
'item_id' => ????,
);
$this->item_model->insertItem($data);
Thanks
For fetching the last inserted ID of variable $item_id in the same transaction of your controller, you can get the ID of record in the same session as follows:
$item_id = $this->db->insert_id();

I do not understand joining tables

I'm using Cake version 2.5.4
I have two tables.
A call arbols which consists of the following fields:
id (int 11)
nombre (varchar (255)
especie:id (int 11)
The second table called fotos consists of the following fields:
id (int 11)
foto (varchar 255)
foto_dir (varchar 255)
arbol_id (int 11)
Although the Arbol model is related to the Especie model,
I leave it aside to the latter because it is not a reason for consultation.
The Arbol Model has a hasMany relationship with the Foto model.
In the Arbol model I have the following:
public $hasMany = array(
'Foto'=> array(
'className' => 'Foto',
'foreignKey' => 'arbol_id',
'dependent' => true
)
);
In the Foto model I have the following:
public $belongsTo = array(
'Arbol'=> array(
'className'=>'Arbol',
'foreign_key'=>'arbol_id'
)
);
Now, inside ArbolsController in public function view ($ id = null)
I want to do the following SQL query:
SELECT * FROM arboles as a join fotos as f on a.id=f.arbol_id
So I return all the photos related to an id of a particular tree passed as parameter in view
If this query is done using MySQL
$registros=mysqli_query($conexion," select * from arboles as a join fotos as f on a.id=f.arbol_id")
it works.
But if I want to do it using the query method in such ways:
$registros = $this->Arbol->query("select * from arboles as a INNER JOIN fotos as f ON a.id=f.arbol_id");
$registros = $this->Arbol->query("select * from arboles as a INNER JOIN fotos as f ON a.id=f.arbol_id");
It does not work
Reading the Cookbook I see there is a way to make joins.
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
I dont understand her
I would appreciate it if you can explain it to me.
From already thank you very much!
You shouldn't be using the query method directly if you can avoid it.
What you can do is using a standard find, joining your tables with containable (or linkable).
Something like this should work:
$registros = $this->Arbol->find('all', array(
'contain' => 'Foto'
));
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html
There is another way by you can join the tables in cakephp i.e customized joins
Create an array of tables whom you want to join, such as
$joins = array(
array(
'table' => 'fotos',//Table name
'alias' => 'Foto', //Model name
'type' => 'INNER', // type of join
'conditions' => array(
'Arbol.id = Foto.arbol_id'
) //Condition for join
)
);
$this->Arbol->find('all', array(
'joins' => $joins,
'conditions'=> array(Arbol.id => $id),
'fields' => array()
))
This will return all the photos information related to an id

hasMany relation without table having id column

I am using CakePHP 2.5. I am having following table
CompanyMaster:
company_master_id [PK]
Name and other columns
CompanySignatoryDetails: (has many owners for single company)
company_signatory_details_id [PK]
company_master_id [FK]
Name and other columns
Now, I want to get company details with all owners of that company. Here is what I have tried.
$this->CompanyMaster->bindModel(
array(
'hasMany' => array(
'CompanySignatoryDetails' => array(
'className' => 'CompanySignatoryDetails',
'foreignKey' => false,
'conditions' => array(
'CompanySignatoryDetails.company_master_id = CompanyMaster.company_master_id'
),
),
)
)
);
$this->CompanyMaster->recursive = 2;
$company = $this->CompanyMaster->find('first', array(
'fields' => array('CompanyMaster.*'),
'conditions' => $conditions, //company id in condition
));
I am getting following error:
Database Error
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'CompanyMaster.id' in 'field list'
SQL Query:
SELECT `CompanyMaster`.*, `CompanyMaster`.`id` FROM `crawler_output`.`company_master` AS `CompanyMaster` WHERE `CompanyMaster`.`company_master_id` = 1 LIMIT 1
Please let me know how can I bind model without id as column name.
CakePHP will produce a separate query when dealing with hasMany relationships, and therefore you won't be able to reference a field from another table. Only belongsTo and hasOne relationships produce a JOIN.
However, you don't need to add conditions to the relationship. The following should just work fine:
$this->CompanyMaster->bindModel(array(
'hasMany' => array(
'CompanySignatoryDetails' => array(
'className' => 'CompanySignatoryDetails',
'foreignKey' => 'company_master_id',
),
)
));
Don't forget to define your primary keys for CompanyMaster:
class CompanyMaster extends AppModel
{
public $primaryKey = 'company_master_id';
}
and for CompanySignatoryDetails:
class CompanySignatoryDetails extends AppModel
{
public $primaryKey = 'company_signatory_details_id';
}
Well, for instance, let your query looks like this:
select CompanyMaster.*,CompanySignatoryDetails.* from
CompanyMaster as cm inner join CompanySignatoryDetails as cd on
cm.company_master_id=cd.company_master_id
order by cm.company_master_id;
You will get all fields from two tables, ordered by company_master_id field. You may reduce number of fields, displayed by this query, by explicitly designate them like this:
select cm.company_master_id, cd.name from....
HNY!(Happy New Year!!)

CakePHP: Table Joins

I am new to CAKEPHP and using joins for the first time. I read the documentation as well.
Now i have two models, One is for Users and other is for Status.
In Status table i have a foreign Key which is User Id in users table.
I want to use $hasMany with conditions such that if a logged in user Share a status it should update the status table having UID in the foreign key and UID is Users table primary key
I dont know what and how to do that.
What i believe is that it should be something like this
class User extends AppModel
{
var $name = 'User';
var $hasMany = array(
'Status' => array(
'conditions' => array('Status.FK' => 'User.id')
)
);
}
Hope i did it right?
for hasMany put this code in your User Model:
/**
* #see Model::$hasMany
*/
public $hasMany = array(
'Status' => array(
'className' => 'Status',
'foreignKey' => 'Status.FK',
'dependent' => true,
),
);
but The Best way is that using belongsTo in your Status Model,Because belongsTo has fewer queries than hasMany method. and in your controller you can use the Status model to retrieving users with their status. for example:
In Status Model:
/**
* #see Model::$belongsTo
*/
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'Status.FK',
),
);
then In your Controller for find specific rows from database you can use :
$this->recursive = 1;
$this->Status->find('all',array('conditions' => array('User.id' => $id)));

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.