relation definition not for primary index columns - yii

Database structure is
Yii::app()->db->createCommand()->createTable('ar_table_column', array(
'col_int1' => 'integer NULL',
'col_int2' => 'integer NULL',
'col_int3' => 'integer NULL',
'col_id' => 'pk',
));
Yii::app()->db->createCommand()->createTable('ar_table', array(
'table_int1' => 'integer NULL',
'table_int2' => 'integer NULL',
'table_int3' => 'integer NULL',
'table_id' => 'pk',
));
Yii::app()->db->createCommand()->createIndex('ar_table_idx', 'ar_table',
'table_int1', true);
I need such a relation - table can have many columns bound with ar_table_column.col_int2 = ar_table.table_int1 (not primary key, but note that table_int1 is unique). I need this relation from column point of view, i.e. I need to have access to table from each column.
First trial:
'table' => array(self::BELONGS_TO, 'ArTable', '',
'on' => 't.col_int2=table.table_int1', ),
And this is a half-good solution. There are 2 cases. First:
$columnInRelation = ArColumn::model()->with('table')->find();
$tableInRelation = $columnInRelation->table;
var_export($tableInRelation->attributes);
and it works well - I get correct array of attributes.
Second case:
$columnInRelation = ArColumn::model()->find();
$tableInRelation = $columnInRelation->table;
var_export($tableInRelation->attributes);
and there I get a SQL error from query:
SELECT table.table_int1 AS t1_c0, table.table_int2 AS t1_c1, table.table_int3 AS t1_c2, table.table_id AS t1_c3 FROM ar_table table WHERE (t.col_int2=table.table_int1)
Error is obvious.
How should I define relation to have it available in both cases - using with() and not using ?

Relation should be according to http://www.yiiframework.com/doc/guide/1.1/en/database.arr
'table' => array(self::BELONGS_TO, 'ArTable', array('col_int2' => 'table_int1')),

Related

Sorting in yii 1.1

I have question regarding yii 1.1 sort.
I have three tables ticket, repairLogs and part table .
Following relations have been defined in Ticket model.
'repairLogs' => array(self::HAS_MANY, 'RepairLog', 'ticket_id', 'order'=>'ts DESC'),
and in repairLogs Table
'part' => array(self::BELONGS_TO, 'Part', 'part_id'),
Part table has a column 'number' and I want to sort the data based on "number". Can anyone guide me how to do this since I am new to the yii 1.1 framework.
You can do this during the find()
Ticket::model()->with(array('part', 'repairLogs'))->findAll(
array(
// your conditions here
'order' => 'part.number DESC', // "part" is the alias defined in your relation array (in the Ticket model file)
'limit' => 10,
)
);
If you are using A dataProvider, you can set it as a default order:
new CActiveDataProvider('Ticket', array(
'criteria' => $criteria, // you criteria that should include the "with" part
'sort' => array(
'defaultOrder' => 'part.number DESC',
)
));

How to get record with same fixture in Yii unit test

Its a parent child relation,
In childGroup1, getting error during accessing 'PARENT_ID' attribute.
The given error is Trying to get property of non-object.
I am having access dynamically.
How to get PARENT_ID in such case.
return array(
'group1'=>array(
'ID' => 1,
'NAME' => 'Test',
'STATUS' => 1,
),
'childGroup1'=>array(
'ID' => 2,
'PARENT_ID' => $this->getRecord('groups','group1')->ID,
'NAME' => 'Child Test group1',
'STATUS' => 1,
),
);
Since the records are not loaded yet, you cannot use $this->getRecord() to acquire a record. As such, just use plain old array logic to get the record's ID.
$records = array();
$records['group1'] = array(
'ID' => 1,
'NAME' => 'Test',
'STATUS' => 1,
);
$records['childGroup1'] = array(
'ID' => 2,
'PARENT_ID' => $records['group1']['ID'],
'NAME' => 'Child Test group1',
'STATUS' => 1,
);
return $records;
If you need records from other fixtures, just require them.
$groups = require __DIR__.'/group.php';
This, of course, would be what you put at the top of files OTHER than groups.php, in order to gain access to the groups models.

SQL - Select distinct but return all columns with CakePHP Find

I am looking to do the same thing as this using cakephp:
https://stackoverflow.com/a/6127471
$eachRWithCode = $this->MovieReview->find( 'all', array(
'fields' => 'MovieReview.*',
'group' => array('MovieReview.code'),
'recursive' => '-1',
'nofilter' => true,
'order' => 'MovieReview.code'
));
This code gives an error:
ERROR: column "MovieReview.id" must appear in the GROUP BY clause or be used in an aggregate function
what DBMS are you using? Mysql let you show columns that you don't use in aggregate function (but you are not , but ather DBMS don't. So every column you want to show you have to put it in a aggregate function such as MAX() or SUM() or COUNT()
so you have to do something like (assuming you have a score column):
$eachRWithCode = $this->MovieReview->find( 'all', array(
'fields' => array(
'COUNT(MovieReview.id)',
'AVG(MovieReview.score),
'MAX(MovieReview.code)
),
'group' => array('MovieReview.code'),
'recursive' => '-1',
'nofilter' => true,
'order' => 'MovieReview.code'
));

How to do this query condition in cakephp?

How can I make this query the CakePHP way?
SELECT *
FROM uploaded_sales us, sales s
WHERE us.item_id = s.audience_id
The column item_id of uploaded_sales table is not its primary key.
The column audience_id of sales table is not its primary key too.
I tried this one on my model, I'm not getting any errors but it still returns sales as empty:
$reports = $this->find('all',
array(
'joins' => array(
array(
'table' => 'sales',
'alias' => 'Sale',
'type' => 'left',
'conditions' => array('Sale.audience_id' => 'UploadedSale.item_id')
)),
'conditions' => array(
'UploadedSale.month' => $month,
'UploadedSale.year' => $year,
'UploadedSale.company_id' => $company_id,
'UploadedSale.item_type' => $item_type
),
'fields' => $fields
));
return $reports;
Learn about using the Containable behavior in CakePHP:
http://book.cakephp.org/view/1323/Containable
It will make joins a helluva lot easier.

is this a really bad way to do queries across multiple HABTM models?

I am trying to query across two HABTM tables. I have Leases Managers Tenants Properties.
Managers HABTM Tenants
Managers HABTM Properties
Tenants HABTM Leases
What I want to do is find a list of Properties linked to Managers linked to Tenant. I have been able to accomplish the query with the code below BUT I am only able to retrieve Property_id (from the Managers_Property model) and not Property.name (from the Property model).
I get the nagging feeling I am doing something very wrong or unnecessary here but I've been banging my head against the wall and haven't been able to figure this out.
$conditionsSubQuery['`ManagersTenant`.`tenant_id`'] = $this->Auth->User('id');
$dbo = $this->Lease->getDataSource();
$subQuery = $dbo->buildStatement(
// SELECT `ManagersTenant`.`manager_id` FROM `managers_tenants` AS `ManagersTenant` WHERE `ManagersTenant`.`tenant_id` = $this->Auth->User('id')
array(
'fields' => array('`ManagersTenant`.`manager_id`'),
'table' => $dbo->fullTableName($this->Lease->LeasesManager->Manager->ManagersTenant),
//'table' => $dbo->fullTableName($this->Lease->Property->ManagersProperty->Manager->ManagersTenant),
'alias' => 'ManagersTenant',
'limit' => null,
'offset' => null,
'joins' => array(),
'conditions' => $conditionsSubQuery,
'order' => null,
'group' => null
),
$this->Lease->LeasesManager->Manager->ManagersTenant
//$this->Lease->Property->ManagersProperty->Manager->ManagersTenant
);
$subQuery = ' `ManagersProperty`.`manager_id` IN (' . $subQuery . ') ';
$subQueryExpression = $dbo->expression($subQuery);
$conditions[] = $subQueryExpression;
$properties = $this->Lease->Property->ManagersProperty->find('list', array(
'conditions' => $conditions,
'fields' => array('property_id',),
'recursive' => 3
)
);
Any help is much appreciated.
Seems like you should be using the Containable behavior: http://book.cakephp.org/view/1323/Containable
$contain = array(
'Manager' => array(
'Property'
)
);
$conditions = array('Tenant.id' => $this->Auth->user('id'));
$tenants = $this->Tenant->find('first', array('conditions'=>$conditions, 'contain'=>$contain));