how to get lable of related model in Yii CDetailView? - yii

Is there any way to access relative model lable? Here w_experience is defined in worker and because $model has not this lable, W Experience appears instead of worker model value!
$this->widget('zii.widgets.CDetailView',
array( 'data'=>$model,
'attributes'=>array(
array('name'=>'w_experience', 'value'=>$model->worker->w_experience==NULL?'-':$GLOBALS['worker_experience_options'][$model->worker->w_experience]),
),
'cssFile' => Yii::app()->theme->baseUrl."/css/darktable.css", )
);

Use
array(
'name' => 'worker.w_experience',
'value' => ...
),
where worker is the name of your relation.
Attribute names are usually resolved using CModel::getAttributeLabel. If your model is derived from CActiveRecord, like all database-backed models are by default, its getAttributeLabel implementation can fetch labels from related objects like this.

Related

FUELPHP ORM: Database view 'viewname' is defined without columns

I am using ORM in FuelPHP to fetch some data on a table view I created in my data base.
I followed the instruction that is given here but I'm getting an error as seen on the title above. Here is a screenshot of the error for reference (http://prntscr.com/72ssqc).
Here is the code:
http://pastebin.com/ips5VCzV
Here is a screenshot of the view Table:
http://prntscr.com/72st1e
Your view definition is wrong, it misses the 'columns' array, as the message explains.
protected static $_views = array(
'hugot_summary' => array(
'columns' => array(
'id',
'user_id',
'photo_id',
'hugot',
'url',
'comment_count',
'upvotes',
'created_at',
'updated_at'
),
),
);

yii CGridView dataprovider and filter

I know we can show a gridview with a model and it's search method and filter the results, but can we make a gridview with another dataprovider and another model like this and filter its results? Does filter needs to be a part of dataprovider?
$attr = Yii::app()->request->getParam($name);
$model = new User('search');
$model->unsetAttributes();
$model->setAttributes($attr);
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $myDataProvider,
'filter' => $model,
'columns' => array(
array(
'name' => 'username',
'type' => 'raw',
'value' => 'CHtml::encode($data->username)'
),
array(
'name' => 'email',
'type' => 'raw',
),
),
));
The above code doesn't work and I need to add a filter on a previously made data provider.
Btw $attr has a valid data, but grid is not filtered.
$model doesn't affect $myDataProvider since the data provider is not obtained using this model.
$model->search() returns a CActiveDataProvider which contains a CDbCriteria instance. Different CDbCriteria can be combined using mergeWith(). So if you would like the data to be filtered using the values from the $model
...
$model->setAttributes($attr);
$newDataProvider=$model->search();
$myDataProvider->criteria->mergeWith($newDataProvider->criteria);
$this->widget('zii.widgets.grid.CGridView', array(
...
Filter does not need to be a part of dataprovider, but data provider needs to take the model into account, if you want to use it for filtering.
The way this is done by default is to create the data provider using search method on your model, which sets conditions of your data provider based on model values, like so:
'dataProvider' => $model->search()
There is nothing preventing you from creating different data provider, for example:
'dataProvider' => $model->createAnotherDataProvider()
And in your User model:
public function createAnotherDataProvider() {
{
// create your second data provider here
// with filtering based on model's attributes, e.g.:
$criteria = new CDbCriteria;
$criteria->compare('someAttribute', $this->someAttribute);
return new CActiveDataProvider('User', array(
'criteria' => $criteria,
));
}

yii CGridView show only logged-in user's records in many_many relation

I have two tables: user and asset and there is user_asset table that makes many_many relation
Now I want to show only the assets related with logged-in user in CGridView (user_id comes from Yii::app()->user->id)
How to write a criteria that makes it possible?
1) You need to define your relations in both of the model
user:
'assets' => array(self::MANY_MANY, 'Asset', 'user_asset(user_id, asset_id)'),
asset:
'users' => array(self::MANY_MANY, 'Asset', 'user_asset(asset_id, user_id)'),
2) You Create a dataProvider that will fetch only the recquired datas (define it in a model (best) or a controller bu not in a view):
$dataProvider=new CActiveDataProvider('Asset', array(
'criteria'=>array(
'with'=>array(
'users'=>array(
'condition' => 'id = ' . Yii::app()->user->id
),
),
),
...
));
3) You give to your CGridView the good provider:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
...
));
The code is given as example, you should adapt it to your need!
I got it work, adding this inside the Model class's search method:
$criteria->with=array(
'users'
);
$criteria->together = true;
$criteria->condition = "users_users.user_id='".Yii::app()->user->id."'";
... and inside CActiveDataProvider declaration:
'criteria'=>array(
'with' => 'users',
'together'=>true,
'condition'=>'users_users.user_id = '.Yii::app()->user->id,
),
Maybe not the best way but does what needed. users_users is sql table alias by Yii, I got a hint from error message :)

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

yii 'through' relation search

I have the following tables.
User:
---------
id<br>
firstName
Project:
---------
id<br>
Name
StaffingManager
---------------
id<br>
User_id(FK)<br>
Total_Staff<br>
StaffingProjectMonth
-----------------------
id<br>
Project_id(FK)<br>
StaffingManager_id(FK)<br>
I want to define the relations in StaffingProjectMonth model
This is the default relation defined by YII using gii
public function relations()
{
return array(
'project' => array(self::BELONGS_TO, 'Project', 'Project_id'),
'staffingManager' => array(self::BELONGS_TO, 'StaffingManager', 'StaffingManager_id'),
);
}
I was able to get the ProjectName and search by ProjectName.
I want to get the UserfirstName and search by that.
I defined the relation this way.
return array(
'project' => array(self::BELONGS_TO, 'Project', 'Project_id'),
'staffingmanager' => array(self::BELONGS_TO, 'StaffingManager', 'StaffingManager_id'),
'user'=> array(self::HAS_MANY,'User',array('User_id'=>'id'),'through'=>'staffingmanager' ),
);
and in search method I did this:
$criteria->with = array('project','user');
//$criteria->compare('id',$this->id);
$criteria->compare('Name',$this->Project_id,true);
$criteria->compare('firstName',$this->StaffingManager_id,true);
and in the view:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'staffing-project-month-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
// 'id',
array('name'=>'Project_id','header'=>'Project','value'=>'$data->project->Name',),
array('name'=>'StaffingManager_id','header'=>'User','value'=>'$data->staffingmanager->user->firstName',),
..............
only the search by project name works. Able to sess the UserfirstName but unable to search by the firstName. Some wrong in defining relations.
Any help is appreciated. Thanks.
I recommend the following excellent wiki article by redguy, that describes how to search by related model attributes:
Following the approach of this article:
You should declare two new variables in your model:
public $project_name;
public $staffingmanager_firstname;
You should declare these new variables as safe for search in the rules() method:
array( 'project_name,staffingmanager_firstname,...', 'safe', 'on'=>'search' ),
Your search() method criteria should look like this:
$criteria->compare('project.Name',$this->project_name,true);
$criteria->compare('user.firstName',$this->staffingmanager_firstname,true);
In your view file, the 'columns' should be:
array('name'=>'project_name','header'=>'Project','value'=>'$data->project->Name',),
array('name'=>'staffingmanager_firstname','header'=>'User','value'=>'$data->user->firstName',),
Hope this helps.
Best regards...
I had troubles with $criteria->with and ”through“ relation.
Thing was in relation kind. BELONGS_TO doesn't work correct. I switched it to HAS_ONE and inverted id direction — array('parent_id'=>'id'). Now it's working!