Cakephp 3.0 join in three table - mysql

I am trying to fetch the data from three table in cakephp 3.0
There is three table
1) size_category
2) sizes
3) sizerelations
Below is the file wise code
Model SizeCategoryTable.php
public function initialize(array $config)
{
parent::initialize($config);
$this->table('size_category');
$this->displayField('sizeCat_Id');
$this->primaryKey('sizeCat_Id');
// used to associate the table with user table (join)
$this->belongsTo('Users', [
'className' => 'Users',
'foreignKey' => 'CreatedBy',
'propertyName' => 'user'
]);
$this->hasMany(
'Sizerelations', [
'className' => 'Sizerelations',
'foreignKey' => 'Scat_Id',
'propertyName' => 'sizerelations'
]
);
}
Controller SizeCategoryController
public function index($id = null)
{
$customQuery = $this->SizeCategory->find('all', array(
'contain' => array(
'Users',
'Sizerelations' => array(
'Sizes' => array(
'fields' => array('id', 'Size_Code')
)
)
)
));
//debug();die();
$this->set('sizeCategory', $this->paginate($customQuery));
$this->set('_serialize', ['sizeCategory']);
}
I am greeting the error of Sizerelations is not associated with Sizes

Related

Associate tables from different database cakephp 3.0

I have two database with name default and default_history. And tables with name users and wafer_detail_history under default database and order_history under default_history database. want to associate Users table with OrderHistory table.
OrderHistoryTable :-
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('order_history');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->hasMany('WaferDetailHistory', [
'foreignKey' => 'order_id'
]);
$this->belongsTo('Users', [
'foreignKey' => 'created_by',
'joinType' => 'INNER'
]);
}
i used this.
$connection = ConnectionManager::get('default_history');
$this->OrderHistory = TableRegistry::get('OrderHistory');
$this->OrderHistory->setConnection($connection);
$id = 37;
$order_history = $this->OrderHistory->get($id, ['contain' => ['Users']]);
but not able to succeed. getting this error:
Base table or view not found: 1146 Table 'default_history.users'
doesn't exist
I had the same problem few days ago,
You must had 'strategy' => 'select' in your BelongTo to join with the other database
$this->belongsTo('Users', [
'strategy' => 'select'
'foreignKey' => 'created_by',
'joinType' => 'INNER'
]);
Try this on the OrderHistoryTable.php File:
$this->setTable('default_history.order_history');

cakephp 3 using for login another model than users auth

I'm trying to make a login from another model and I have an error.
This is my code for Student Model
var $name= 'Student';
public $components = array(
'Session',
'Auth' => array(
'loginAction' => array(
'controller' => 'students',
'action' => 'login',
'plugin' => 'students'
),
'authError' => 'Did you really think you are allowed to see that?',
'authenticate' => array(
'Form' => array(
'fields' => array(
'username' => 'username', //Default is 'username' in the userModel
'password' => 'password' //Default is 'password' in the userModel
)
)
)
)
);
StudentsController looks like
public function beforeFilter(Event $event) {
parent::beforeFilter($event);
$this->Auth->allow('login');
}
public function login() {
if($this->Session->check('Auth.Student')){
$this->redirect(array('action' => 'login'));
}
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->Session->setFlash(__('Welcome, '. $this->Auth->student('username')));
$this->redirect($this->Auth->redirectUrl());
} else {
$this->Session->setFlash(__('Invalid username or password'));
}
}
}
And the AppController is
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
}
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'students', 'action' => 'login'),
'loginAction' => array('controller' => 'students', 'action' => 'login'),
));
public function beforeFilter(Event $event) {
$this->Auth->authenticate=array (
'loginAction' => [
'controller' => 'Students',
'action' => 'login',
'plugin' => false,
],
'Basic' => ['userModel' => 'Students'],
'Form' => ['userModel' => 'Students']
);
}
And I have the following error
Component class SessionComponent could not be found.
How can I fix it?
Session was deprecated in cakePHP 3, How you are doing is for cake2. In cake 3 you can use RequestHandeler like,
$this->loadComponent('RequestHandler');
OR
public $components = array(
'RequestHandler'
);
then use,
$this->request->Session()->read/write/delete/destroy();
Hope this will work for you :).

yii 1 relation not working in CGridView

I am trying to get relation where companies table have primary key companyID and division table have Foreign key companyID , what I need in where clause is WHERE companies.companyID = division.companies
relation in my model is :
public function relations()
{
return array(
'company' => array(self::BELONGS_TO, 'Companies', 'CompanyID'),
);
}
My Model->search() function is
public function search()
{
$criteria=new CDbCriteria;
$criteria->with ='company';
$criteria->compare('company.CompanyID', $this->CompanyID, true );
$criteria->compare('DivisionID',$this->DivisionID, true);
$criteria->compare('CompanyID',$this->CompanyID, true);
$criteria->compare('Name',$this->Name,true, true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
and my admin.php view is:
<?php
$this->breadcrumbs = array(
'Divisions' => array('index'),
'Manage',
);
$this->menu = array(
array('label' => 'List Divisions', 'url' => array('index')),
array('label' => 'Create Divisions', 'url' => array('create')),
);
");
?>
<div class="row">
<?php
$this->renderPartial('_dropdownfilter', array(
'model' => $model,
));
?>
</div><!-- end dropdown partial form -->
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'divisions-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
'CompanyID',
'DivisionID',
'Name',
array(
'class' => 'CButtonColumn',
),
),
));
?>
You need to add together=true to your criteria.
$criteria->together = true;
It'll add join to query. Some information about lazy loading http://www.yiiframework.com/wiki/527/relational-query-lazy-loading-and-eager-loading-with-and-together/
If you want to display company name,just do this in view.Don't change anything in model->search().
array(
'name'=>'Name',
'value'=>$model->company->name //here name is column name in company table.
),
In your gridview code do the following changes.
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'divisions-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
array(
'name' => 'companies',//fied from division table which refers to companyId from company table.
'header' => 'Company',
'value' => '$data->company->company_name'
),
'CompanyID',
'DivisionID',
'Name',
array(
'class' => 'CButtonColumn',
),
),
));
And in your model->search()
public function search()
{
$criteria=new CDbCriteria;
$criteria->with ='company';
$criteria->compare('company.company_name', $this->companies, true );
$criteria->compare('DivisionID',$this->DivisionID, true);
$criteria->compare('CompanyID',$this->CompanyID, true);
$criteria->compare('Name',$this->Name,true, true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}

How to connect 3 tables in yii2 and display in Gridview then make sorting work correctly

I have used the gii tool to create crud application. I have 3 tables the tbl_targetcities, lib_cities, and lib_provinces. I was able to connect lib_cities to tbl_targetciteis but not the lib_provinces. And also the sorting of city / Municipality does not work. It seems that it sorts according ti the ID.
tbl_target_cities
lib_cities
lib_provinces
sample View
So far here is my relation in the model.
public function getCityName()
{
return $this->hasOne(LibCities::className(),['city_code'=>'city_code']);
}
in my view file...
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'attribute'=>'city_code',
'value'=>'cityName.city_name'
],
[
'attribute'=>'prov code',
'value'=>'cityName.city_name'
],
'kc_classification',
'cluster',
'grouping',
'priority',
'launch_year',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
How to display the prov_name from lib_provinces???
EDIT to answer user2839376 question in the comment box
IN THE SEARCH MODEL CLASS
$query = TblSpBub::find();
$query->joinWith('brgyCode')->joinWith(['cityCode'])->joinWith(['cityCode.provCode']);
$covered= LibAreas::find()->where(['user_id'=>yii::$app->user->identity->id])->all();
$query->all();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort'=> ['defaultOrder' => ['id'=>SORT_DESC]],
]);
$dataProvider->sort->attributes['city'] = [
'asc' => ['lib_Cities.city_name' => SORT_ASC],
'desc' => ['lib_Cities.city_name' => SORT_DESC],
];
$dataProvider->sort->attributes['province'] = [
'asc' => ['lib_provinces.prov_name' => SORT_ASC],
'desc' => ['lib_provinces.prov_name' => SORT_DESC],
];
In LibCities model add new relation:
public function getProvince()
{
return $this->hasOne(LibProvince::className(),['prov_code'=>'prov_code']);
}
And change getCityName relation. You should add with() for relation:
public function getCityName()
{
return $this->hasOne(LibCities::className(),['city_code'=>'city_code'])->with(['province']);
}
And in view correct your columnto this:
[
'attribute'=>'prov code',
'value'=>'cityName.province.prov_name'
],
You have to use the function relations() in models.
In tbl_target_cities model:
public function relations()
{
return array(
'city' => array(self::HAS_ONE, 'LibCities', 'city_code'),
);
}
In LibCities model :
public function relations()
{
return array(
'province' => array(self::HAS_ONE, 'LibProvinces', 'prov_code'),
'targets' => array(self::HAS_MANY, 'TargetCity', 'city_code',
);
}
This will allowed you to jump throw the LibCities model,
now you can simply acces to prov name like this :
$model->city->province->prov name;
Note : You need to have the 3 models defined.
EDIT
array(
'name' => 'province name',
'value' => $data->city->province->prov_name;
),
Done it, Heres how.
in addition to the above code (original post)
// in Model I added an additional function
public function getTaskowner()
{
return $this->hasOne(Tasks::className(), ['id' => 'task_id'])
->with(
['location','taskowner']
);
}
and in view i did this
....
'columns' => [
....
[
'class' => 'kartik\grid\DataColumn',
'value'=> 'tasks.location.taskowner.name',
.....
],
.....
and it worked
key points. used an array with the 'with->(..)' to include both then in the view added 'tasks.location.taskowner.name', to join them all

CakePHP find Queries with aliases SQLSTATE[42S22] Error

I'm having a weird problem with my relationships/aliases in CakePHP and now its preventing me from accessing my data correctly.
I have:
User hasMany CreatorModule (alias for Module)
User HABTM LearnerModule (alias for Module)
Module belongsTo Creator (alias for User)
Module HABTM Learner (alias for User)
And I'm trying to call:
$id = $this->Module->User->findByEmail($email);
$modules = $this->Module->findByUserId($id['User']['id']);
The queries that get generated aren't correct - the table-alias is wrong. I'm not sure which of the above is responsible but I get:
SELECT
`Creator`.`id`,
`Creator`.`email`,
`Creator`.`organization`,
`Creator`.`name`,
`Creator`.`password`,
`Creator`.`verified`,
`Creator`.`vcode`
FROM
`snurpdco_cake`.`users` AS `Creator`
WHERE
`User`.`email` = 'foo#example.com' # <--
LIMIT 1
I figured out that the error is that CakePHP should change 'User' in the WHERE clause to Creator, but doesn't, even if I use the alias. How do I complete this query correctly.
Further, as a related problem, I find that I can no longer use User in my model calls etc now that I have defined aliases. Is there a way around this?
EDIT: As requested, here is my model code defining the aliases:
class User extends AppModel {
public $name = 'User';
public $uses = 'users';
public $hasMany = array(
'OwnedModule' => array(
'className' => 'Module',
'foreignKey' => 'user_id',
'dependent' => true
));
public $hasAndBelongsToMany = array(
'LearnerModule' => array(
'className' => 'Module',
'joinTable' => 'modules_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'module_id',
'unique' => 'keepExisting',
));
//The rest of the Model
}
//Different file, condensed here for spacing
class Module extends AppModel {
public $name = 'Module';
public $belongsTo = array(
'Creator' => array(
'className' => 'User'));
public $hasAndBelongsToMany = array(
'Learner' => array(
'className' => 'User',
'joinTable' => 'modules_users',
'foreignKey' => 'module_id',
'associationForeignKey' => 'user_id',
'unique' => 'keepExisting',
));
//The rest of the Model
}
try
$id = $this->Module->Creator->find('first',
array('conditions' => array('Creator.email' => $email)
);
$modules = $this->Module->findByCreatorId($id['User']['id']);