cakephp2 join two tables from two database - mysql

I have developing a SAAS based site, which i have to join two tables from two DBs, say table1 from DB1 and table2 from DB2. I have to get the matching records from table1 and table 2 using join in cakephp, but it throws error as below :
Error: SQLSTATE[42000]: Syntax error or access violation: 1142 SELECT command denied to user 'dbname'#'localhost' for table 'table_name' .
can anyone explain me how to done this using cakephp .
class table1 extends AppModel{
public $useDbConfig = 'DB1';
}
Class table2 extends AppModel{
public $useDbConfig = 'DB2';
function desc(){
$this->Store->useDbConfig = 'default';
$rslted = $this->find('all',array(
'conditions' => array('Jewel.id' =>1),
'joins' => array(
array(
'alias' => 'Store',
'table' => 'stores',
'type' => 'INNER',
'conditions' => 'Store.id = Jewel.store_id'
)
)
));
return $rslted;
}
}
while called the desc function from controller is not working throws error:
Base table or view not found: 1146 Table 'site1.site1_stores' doesn't exist
but using the hasmany or belongsto on model will working , the join query is not working in controller

Please follow the steps:
Step 1: Create two models named Jewel.php and Store.php for model classes
Content of Jewel.php
class Jewel extends AppModel{
public $useDbConfig = 'DB1';
}
Content of Store.php
Class Store extends AppModel{
public $useDbConfig = 'DB2';
}
Step 2: Create one method in Store model as shown below
function getData(){
$this->bindModel(array(
'hasOne' => array(
'Jewel' => array(
'foreignKey' => false,
'conditions' => array('Store.id = Jewel.store_id')
)
)
));
$returnData = $this->find('all',array('conditions' => array('Jewel.id' =>1)));
}
Hope this will help!

Related

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!!)

Yii 2.0 table alias in SQL query

I am using Yii2.0 and I have following error when I doing filtering with relationship:
Exception (Database Exception) 'yii\db\Exception' with message
'SQLSTATE[42S22]: Column not found: 1054 Unknown column
'userContact.email' in 'where clause' The SQL being executed was:
SELECT tbl_user.* FROM tbl_user LEFT JOIN tbl_user_contact ON
tbl_user.id = tbl_user_contact.user_id WHERE
userContact.email='me#me.com'
And it is obvious that the table name alias is not given. Following is my code that generate the query above:
Class Files
class User extends ActiveRecord{
public function getUserContacts(){
return $this->hasMany(UserContact::className(), ['user_id' => 'id']);
}
}
class UserContact extends ActiveRecord {
public function getUser(){
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
}
Query
User::find()->joinWith('userContacts', false)
->where(['userContact.email' => $email])
->one();
I follow the instruction given here.
Is there a way to have the alias in the query?
Use method "alias('string')".
User::find()->alias('u')->joinWith(['userContacts' => function($query) use ($email){
$query->alias('uc')->where(['uc.email' => $email])
}])
->one();
Look this API doc
In MySQL, your user table is called tbl_user_contact. However, you are referring to it as userContact, which results in the error.
When adding conditions, you should refer to fields using the actual table name. Here's the proper code:
User::find()->joinWith('userContacts', false)
->where([UserContact::tableName().'.email' => $email])
->one();
You could just replace UserContact::tableName().'.email' with tbl_user_contact.email, but using tableName() is better practice.
ActiveQuery extends of Query, you can use methods of query in ActiveQuery:
$query = \app\models\db\AnuncioConsulta::find();
$query->from(\app\models\db\AnuncioConsulta::tableName() . ' as ac' );
$query->join = [
['INNER JOIN', 'anuncio as a' , ' a.id = ac.anuncio_id AND a.status = 1 '],
['INNER JOIN', 'autor as au' , ' au.id = a.autor_id AND au.agente_inmobiliario = 0 '],
['INNER JOIN', 'usuario as u' , ' u.id = au.object_id '],
];
$query->andWhere('ac.news =:status' , [':status' => 1 ]);
$query->andWhere('ac.delete =:status' , [':status' => 0 ]);
$query->andWhere('u.id =:userId' , [':userId' => Yii::$app->user->id ]);
return new \yii\data\ActiveDataProvider([
'query' => $query,
]);

Cakephp: How to link models if each model connected to other by some foreign key

I am new to Cakephp and I don't found any solution for my problem.
I have three tables-
medicines:
id|Name|company_id
companies:
id|Name|city_id
cities:
id|Name
I have to select medicines.name, companies.name and cities.name where ids are matched so
how I cand do this by Cakephp method.
I know the simple sql query for this:
SELECT medicines.name, companies.name and cities.name FROM medicines, companies, cities WHERE medicines.company_id=companies.id AND companies.city_id=cities.id
Thanks in Advance
Have you tried reading the book? It is well explained there: Associations: Linking Models Together
Defining relations between different objects in your application
should be a natural process. For example: in a recipe database, a
recipe may have many reviews, reviews have a single author, and
authors may have many recipes. Defining the way these relations work
allows you to access your data in an intuitive and powerful way.
Examples from the book:
class User extends AppModel {
public $hasOne = 'Profile';
public $hasMany = array(
'Recipe' => array(
'className' => 'Recipe',
'conditions' => array('Recipe.approved' => '1'),
'order' => 'Recipe.created DESC'
)
);
}
class User extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
public $hasAndBelongsToMany = array(
'MemberOf' => array(
'className' => 'Group',
)
);
}
class Group extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
public $hasAndBelongsToMany = array(
'Member' => array(
'className' => 'User',
)
);
}

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)));