Accessing field in related table through Foreign Key in Yii - yii

I have three tables
1. tbl_employee: id(PK), name, position_id(FK), type_id(FK)
2. tbl_position: id, position
3. tbl_type : id, type
I want to display records in field position like what sql does below.
SELECT tbl_employee.name, tbl_position.position
FROM tbl_employee, tbl_position
WHERE tbl_employee.position_id = tbl_position.id AND tbl_position.position LIKE '%Designer';
In my EmployeeController
public function actionIndex(){
$dataProvider=new CActiveDataProvider('Employee', array(
'criteria'=>array(
'select'=>'t.name, tbl_position',
'with'=>array(
'position'=>array('select'=>'position'),
'type'=>array('select'=>'type'),
),
'condition'=>"tbl_position.position LIKE '%Designer'",
),
));
$this->render('index',array('dataProvider'=>$dataProvider,));
}
and in my models
public function relations(){
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'position' => array(self::BELONGS_TO, 'Position', 'position_id'),
'type' => array(self::BELONGS_TO, 'Type', 'type_id'),
);
}
and this is my view
<?php $this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'id',
'name',
array(
'name'=>'position_id',
'value'=>CHtml::encode($model->position->position),
),
array(
'name'=>'type_id',
'value'=>CHtml::encode($model->type->type),
)
),
)); ?>
The error I've got is:
Active record "Employee" is trying to select an invalid column "tbl_position".
Note, the column must exist in the table or be an expression with alias.
How can I access position field in tbl_position by using join?What is the correct syntax for achieving that purpose.
Many thanks

'select'=>'t.name, position.position',
'condition'=>"position.position LIKE '%Designer'",
or
$model = TblEmployee::model()->with('position','type')->findall(array("condition"=>"position.position LIKE '%Designer'"));

Here I find the solution, but actually your answer was very close
public function actionIndex(){
$dataProvider=new CActiveDataProvider('Employee', array(
'criteria'=>array(
'select'=>'t.name',
'with'=>array(
'position'=>array('select'=>'position'),
'type'=>array('select'=>'type'),
),
'condition'=>"position.position LIKE '%Designer'",
),
));
$this->render('index',array('dataProvider'=>$dataProvider,));
}

Related

Yii CGridView data is foreign key

I'm having some hard time with CGridView, where one field is the foreign key to another table.
There is a table called Person which contains an id_scholarity
And a table Scholarity where id_scholarity is PK. I want to show the description of scholarity and not the id number.
Gii has created the relations:
In Scholarity model:
return array(
'person' => array(self::HAS_MANY, 'PERSON', 'ID_SCHOLARITY'),
);
In Person Model
return array(
'id_scholarity' => array(self::BELONGS_TO, 'SCHOLARITY', 'ID_SCHOLARITY'),
);
And finally my grid (in views/person/admin.php)
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'person-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'NAME',
array('name'=>'ID_SCHOLARITY', 'value'=>'$data->ID_SCHOLARITY->DESCRIPTION'),
array(
'class'=>'CButtonColumn',
),
),
));
The page just gets blank (by the way, how can I make yii show errors?).
What I'm doing wrong?
try
'columns'=>array(
'NAME',
array('value'=>'$data->id_scholarity->DESCRIPTION'),
array(
'class'=>'CButtonColumn',
),
),
when you access other table with arrow operator you have to access it using relation name not the attribute name. In your code relation name is id_scholarity but you are using ID_SCHOLARITY .

Displaying value from join table in Yii CgridView

I have this very simple table in my view and I'm trying to display value from joined table:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'skills-grid',
'dataProvider'=>$model->searchWithStudentSuccessRate($id),
'template' => '{items}{pager}',
'cssFile'=>Yii::app()->request->baseUrl. '/themes/'. Yii::app()->theme->name.'/css/table.css',
'htmlOptions'=>array('class'=>'datagrid', 'style'=>'width:550px;'),
'columns'=>array(
array(
'name'=>'name',
),
array(
'name' => 'value',
'header' => Yii::t('MainTrans', 'Value'),
'value' => '$data->student_skills->value',
),
array(
'name' => 'successRate',
'header' => Yii::t('MainTrans', 'Success Rate'),
'value' => '$data->successRate."%"',
),
),
));
And this is the search function:
public function searchWithStudentSuccessRate($id)
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('name',$this->name,true);
$criteria->compare('t.threshold',$this->threshold);
$criteria->with = array('student_skills');
$criteria->together = true;
$criteria->select = array('IFNULL(CASE WHEN ROUND((student_skills.value/t.threshold)*100,0) > 100 THEN 100 ELSE ROUND((student_skills.value/t.threshold)*100,0) END,0) as successRate','*');
$criteria->group = "t.name";
$criteria->condition = 'student_skills.student_id = '.$id;
$criteria->compare('successRate',$this->successRate);
$criteria->compare('student_skills.value',$this->value);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'pagination'=>array(
'pageSize'=>25,
),
'sort'=>array(
'defaultOrder'=>array(
'successRate'=>CSort::SORT_DESC,
),
'attributes'=>array(
'successRate'=>array(
'asc'=>'successRate',
'desc'=>'successRate DESC',
),
'*',
),
),
));
}
But I get error: "Trying to get property of non-object" when I added value column to my CGridView.
Everything works fine without column value (columns successRate and name are fine). Relation should be fine as well. The error I get means that the value doesn't exist but it should since I did something similar in my other views and there it works.
Can anyone tell what's wrong? I'm sure it's something minor but I'm struggling with this embarrasing problem for a while.
Thanks
It means that in some conditions $data->student_skills is NULL. Try change this:
'value' => '$data->student_skills->value',
to this
'value' => 'empty($data->student_skills) ? null : $data->student_skills->value',

yii showing data on cgridview from others table

I'm having problem to show data on cgridview using foreign keys.
This is my case, i have table employee(id, username), client(id, username), and transaction(id, employeeId, clientId). employeeId foreign key to employee.id, and clientId is foreign key to client.id. Now, I want to show employee's name and client's name instead of their id on transaction admin.php.
This is my code:
class Transaction extends CActiveRecord
{
public $client_search;
public $employee_search;
public function rules()
{
return array(
.
.
.
array('id, employeeId, clientId, balance, status, date, client_search, employee_search', 'safe', 'on'=>'search'),
);
}
public function relations()
{
return array(
'employee' => array(self::BELONGS_TO, 'Employee', 'employeeId'),
'client' => array(self::BELONGS_TO, 'Client', 'clientId'),
);
}
public function search()
{
$criteria=new CDbCriteria;
$criteria->with = array( 'client', 'employee' );
$criteria->together = true;
$criteria->compare('t.id',$this->id,true);
$criteria->compare('employee.username', $this->employee_search, true );
$criteria->compare('client.username', $this->client_search, true );
$criteria->compare('t.balance',$this->balance,true);
$criteria->compare('t.status',$this->status);
$criteria->compare('t.date',$this->date,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
//the other functions are there, i don't edit it.
}
that is my model/Transaction.php
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'transaction-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
array(
'header' => 'Employee',
'name' => 'employee_search',
'value' => '$data->employee->username',
),
array(
'header' => 'Client',
'name' => 'client_search',
'value' => '$data->client->username',
),
array(
'class'=>'CButtonColumn',
),
),
));
that is my views/transaction/admin.php.
and this code gave me error Trying to get property of non-object ($data->employee->id marked).
Actually I have succed to show the employee's name instead of employee's id, but, after that I use the same method for the client, and the error appear.
anyone can help me? My method is making public employee_search, add the rules, add the relation, adding $creiteria->with, then change the admin.php. Anyone please help me.
//UPDATE
SOLVED. Its actually my fault. There is an error in the database about the relation (foreign key). My coding is fine.
It's hard to guess without being able to debug your code but here are some things that could help (I'll add more as I can think of them).
It might be because both the default joinType for relations is LEFT OUTER JOIN and maybe you have a Transaction where one of them is null? If you try to access attributes on null object (as opposed to an actual ActiveRecord object), that's precisely the error message you would be seeing.
You could change it by doing:
public function relations()
{
return array(
'employee' => array(self::BELONGS_TO, 'Employee', 'employeeId',array('joinType'=>'INNER JOIN')),
'client' => array(self::BELONGS_TO, 'Client', 'clientId',array('joinType'=>'INNER JOIN')),
);
}
P.S.: INNER JOIN is the same as just JOIN
Not sure if it will help you, but it's worth trying.
More information at: http://www.yiiframework.com/doc/api/1.1/CActiveRecord#relations-detail

cgridveiw to display fetched data via customized query

I am a newbei in yii, when a person clicks on a category display him all products under that particular category in a gridview
view
productcategory
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'admin-grid',
'dataProvider'=>$model->SelectedCategoryProducts,
'filter'=>$model,
'columns'=>array(
'Name',
'Model',
'Brand',
'Price',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
controller
product
public function actionProductcategory($id)
{
$model= Product::model()->SelectedCategoryProducts($id);
var_dump($model);
$this->render('productcategory',array(
'model'=>$model,'id'=>$id,
));
}
model
product
public function SelectedCategoryProducts($id)
{
$dataProvider=new CActiveDataProvider('Product', array(
'criteria'=>array(
'select'=>'name,model,price,brand',
'condition'=>'category=:category',
'params'=>array(':category'=>$id),
)));
var_dump($dataProvider);
return $dataProvider;
}
CException
Property "CActiveDataProvider.sellerSelectedCategoryProducts" is not defined.
PLEASE HELP! I am losing my mind on this ... not able to display in gridview.
Pass $id to your view file.
$this->render('productcategory',array('model'=>$model,'id'=>$id));
Then pass id to model function in ccgridview function.
'dataProvider'=>$model->SelectedCategoryProducts($id),
Hope this might help
Controller file
public function actionProductcategory($id)
{
$model=new Product;
$this->render('productcategory',array('model'=>$model,
'id'=>$id));
}
In View file
'dataProvider'=>$model->SelectedCategoryProducts($id),
UPDATE 1
'columns'=>array(
'name',
'model',
'brand',
'price',
change them to lowercase which are your original column names
$dataProvider=new CActiveDataProvider('Product', array(
'criteria'=>array(
'select'=>'name,model,price,brand',
'condition'=>'category=:category',
'params'=>array(':category'=>$id),
)));
this can retrieve needed data.... first check that data is perfect ... is it right after that take second step....

Yii View, Replacing some database values in CGridView

I am new with Yii, Sorry if my question might be stupid, I am using CGridView to show some fields of my database in a table:
<?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>
<div class="search-form" style="display:none">
<?php $this->renderPartial('_search',array(
'model'=>$model,
)); ?>
</div><!-- search-form -->
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'show-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'title',
'brief',
'tbl_season_id',
'on_season',
array(
'name'=>'status',
'value'=>'Lookup::item("NewsStatus",$data->status)',
'filter'=> Lookup::items('NewsStatus'),
),
array(
'class'=>'CButtonColumn',
),
),
)); ?>
</div>
I want to replace some of the values that are shown, for example, the on_season field is binary and in the table the values are 0 or 1, I want to change this values to Yes and NO,
And tbl_season_id is a foreign key form another table, I would like to get the name of the season and put it instead of the id which is not understandable by the users.
You can refer this wiki article for customizing your column values to your heart's content
Yii Documentataion: cgridview-render-customized-complex-datacolumns
Just remember that the value property can be an expression string, which is later evaluated for each data of rows. So you have a method call there which can dynamically calculate any value for you depending on the current values of that row.
Let you have two table
1): clients 2): projects
Relation is a client has many projects.
in model
and clients model the relation is (the Client table model name is Client)
class Client extends CActiveRecord{
}
and relations() method ;
return array(
'projects' => array(self::HAS_MANY, 'Projects', 'clients_id'),
);
project model the relation is (the project table model name is Projects)
class Projects extends CActiveRecord{
}
and relations() method ;
return array(
'clients' => array(self::BELONGS_TO, 'Client', 'clients_id')
);
Now
now you can use the following to get the client_name replace the client_id in proejct table
in CGridView
'dataProvider' => $model->search(),
'columns' => array(
'id',
'project_name',
array(
'name' => 'client Name',
'value' => '$data->clients->name', //where name is Client model attribute
),
)
and
Project view page in CDetailView you can use the following
'data' => $model,
'attributes' => array(
'id',
'project_name',
array(
'name'=>'Client Name',
'value'=>$model->clients->name ,
),
)
if you have client relation with company table (a company has many clients )
client model
'company' => array(self::BELONGS_TO, 'Company', 'company_id'),
you can also get the company name by following method in
index (CGridview)
array(
'name' => 'client Name',
'value' => '$data->clients->company->name', //where name is company model attribute
),
and in view CDetailView
array(
'name'=>'Client Name',
'value'=>$model->clients->company->name ,
),