Yii - Self Referencing Table - php

This is my category table
id category parent_category_id
1 animal NULL
2 vegetable NULL
3 mineral NULL
4 doggie 1
5 potato 2
6 hunting 4
my yii grid view shows parent category id instead of name.
how can i display the parent category name in grid view.
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'category-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'category',
'parent_category_id',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
what changes i have to make in the above code.
thanks.

First step - define relation in model class:
public function relations()
{
return array(
'parent'=>array(self::BELONGS_TO, 'Category', 'parent_category_id'),
);
}
where Category - is name of AR model class, parent_category_id - foreign key referencing to itself.
Step 2 - CGridView, columns attribute:
...
'columns'=>array(
'id',
'category',
array(
'name'=>'Parent category', // col title
'value'=>function (Category $data){
if($data->parent_category_id)
return $data->parent->category; // "parent" - relation name, defined in "relations" method
return "-= root category =-";
}
),
)
...
Note: code above requires php version>=5.3. Otherwise you have to avoid using anonymous function

'columns'=>array(
.....
array('name'=>'id','value'=>'$data->Category->name'),
)
or create function inside call getCategoryName() and retreive name
'columns'=>array(
.....
array('name'=>'id','value'=>'$data->getCategoryName()'),
)
public function getCategoryName()
{
$equery= Category::model()->find("id=$this->id");
$cnm=$equery['Category'];
return $cnm;
}

Related

How to assign new values to saved data in yii 1?

I have following code in my controller:
public function actionAdmin()
{
$model=new MForm('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['ChManageForm']))
$model->attributes=$_GET['ChManageForm'];
$this->render('admin',array(
'model'=>$model,
));
}
and
const member=1;
const district=2;
My view(called admin)
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'ch-manage-form-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'form_name',
'region',
'phone_number',
'email',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
1 and 2 appears in the column called name(in my view file) and values of this column are saved in integer format. I need to show(in my view(admin)) member and district instead of numbers(e.g member instead of 1). How can I do it?
You can also specify the grid view column like this (doesn't require a helper in your model):
array(
'name'=>'form_name',
'value'=>'$data->form_name ? \'Member\':\'District\'',
'type'=>'text',
),
this works great if you only have 2 value in the variable.
Visit this URL to get more details.
http://www.yiiframework.com/forum/index.php/topic/14845-if-condition-inside-cgridview/
EDIT:
IF you have more than 2 values,
Model which you use to CGridView:
public function getValueText() {
return $this->getValueTextOptions[$this->form_name];
}
public function getValueTextOptions() {
return array(
1 => 'Member',
2 => 'District',
);
}
View with CGridView:
array(
'name'=>'form_name',
'value'=>'$data->getValueText()',
)

Yii CGridView, I can't display fields form other model using HAS_MANY relationship

I have a HAS_MANY relation between 2 models, i use bookID as foreign key
model 1 - Importedbooks, Importedbooks can have many CountryOfImport
public function relations()
{
return array(
'CountryOfImportObj'=>array(self::HAS_MANY, 'CountryOfImport', 'bookID')
);
}
model 2 CountryOfImport, CountryOfImport belongs to Importedbooks
public function relations()
{
return array(
'ImportBooksObj'=>array(self::BELONGS_TO, 'Importedbooks', 'bookID')
);
}
Now, For my CGridView i am using a model->search()of the Importedbooks model as my dataProvider, From here is where i get stuck.
CGridView
$data = $model->search();
$data->setPagination(array('pageSize'=>'5'));
$data->criteria->addCondition('active = "yes"');
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$data
,'filter'=>$model
,'pager'=>array('header'=>'')
,'columns'=>array(
'id',
'bookYear',
'bookTitle',
'DISPLAY VALUE FROM OTHER model HERE'
)
)
);
DataProvider of the Imported books model, i'm using this as my data provider for the grid
public function search()
{
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('bookID',$this->bookID);
$criteria->compare('countryName',$this->countryName,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
The relation works because i can use below code in my controller to get a field(countryName) from the other model
$model = Importedbooks::model()->with('CountryOfImportObj')->findbyPK(3);
print_r($model->CountryOfImportObj[0]->countryName);
Such as Importedbooks have many CountryOfImport, in one row you must show or all country names or concreet names depending on ID or countryName or some other attribute.
You can pass anonymous function as value:
'columns' => array(
'id',
'bookYear',
'bookTitle',
array(
'header' => 'Countries',
'type' => 'raw',
// if you have defined counrtyName attribute in 'Importedbooks' model, if not you can remove this row
// also CGridView 'uses' attribute 'name' for filtering or sorting
'name' => 'countryName',
'value' => function($data, $row) { //$data is item of DataProvider, $row is number of row (starts from 0)
$countries = CHtml::listData((array)$data->CountryOfImportObj, 'id', 'countryName');
return implode(', ', $countries);
}
)
)
If you want to filter or sort by external attributes too, you must "declare them"
Thanks!

Yii Framework, how to fetch related table data?

I am new to yii and the model relation is new to me. I am currently doing a system that has a table structure:
products
PK id
brand
product_locales
PK id
FK product_id
name
locale
product_relations
PK id
FK product_id
FK related_id
my Product model relation:
public function relations()
{
return array(
'productlocales' => array(self::HAS_MANY, 'ProductLocale', 'product_id'),
'relations' => array(self::MANY_MANY, 'Product', 'product_relations(product_id, related_id)')
);
}
then my Product Locale Relation:
public function relations()
{
return array(
'product' => array(self::BELONGS_TO, 'Product', 'product_id')
);
}
in my Product Controller when I call this code:
$product = ProductLocale::model()->findByPk(1);
var_dump($product->product->relations);
it outputs the id and brand of a related product from the product table. but what I want to output is all the locales of the product, which is the name and the locale.
Can anyone help me out with this?
Thanks in advance.
I don't understand the product_relations table, and seems like the relation whith Product is HAS_MANY, not MANY_MANNY.
In any case, if I have understood, you need find the id of product and then find all the product_locale with this id:
$prodLoc=ProductLocale::model()->findByPk(1);
$arrayProdLoc=ProductLocale::model()->findAllByAttributes('product_id'=>$prodLoc->product_id);
ArrayProd will have models for all product_locale related with the same product.
If you want show this information in a gridview, you probabli will want a DataProvider:
$prodLoc=ProductLocale::model()->findByPk(1);
$provider=CActiveDataprovider('ProductLocale',array (
'criteria'=>array(
'condition'=>'product_id='.$prodLoc->product_id,
));
You can also define a new self-relation into product_locale Model:
public function relations()
{
return array(
'product' => array(self::BELONGS_TO, 'Product', 'product_id'),
'productsLocRelated'=>array(self::HAS_MANY,'ProductLocale',array('product_id'=>'product_id')),
);
}
So you can have all products_locale by:
$prodLoc=ProductLocale::model()->findByPk(1);
$arrayProdLoc=$prodLoc->productsLocRelated;
Note: I haven't tested the code.

YII EMongoDocumentDataProvider

My collactions-category have 3 fields- _id ,name, parent_id
parent_id is _id of parent
In actionIndex
public function actionIndex()
{
$dataProvider=new EMongoDocumentDataProvider('Category');
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
}
How I can replace parent_id by name of parent category
You don't provide enough information but I assume you wish to use this with GGridView. That is where you will have to do this, within the declaration of the CGridView:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'columns'=>array(
array(
'name' => 'Parent',
'value' => '$data->parent->name'
)
)
);
parent in $data->parent is the name of the relation within your model to the parent model.

Setting Up Yii MANY_MANY Relationship

I am trying to set up a MANY_MANY Relationship in Yii using Active Record.
I have three tables
profile
profile_id
profile_description
category
category_id
category_name
profile_category
profile_id
category_id
My models are Profile, Category, and ProfileCategory.
I am trying to run a query using the category_id that will pull up all of the profiles that are in that category.
This is the information in the category model.
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(
'profiles'=>array(
self::MANY_MANY,
'Profile',
'profile_category(category_id, profile_id)',
),
'profile_category'=>array(
self::HAS_MANY,
'ProfileCategory',
'category_id',
),
);
}
Profile Model
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(
'categories'=>array(
self::MANY_MANY,
'Category',
'profile_category(profile_id, category_id)'
),
'profileCategory'=>array(
self::HAS_MANY,
'ProfileCategory',
'profile_id'
),
);
}
ProfileCategory Model
public function relations()
{
return array(
'category'=>array(
self::BELONGS_TO,
'Category',
'category_id',
),
'profile'=>array(
self::BELONGS_TO,
'Profile',
'profile_id',
),
);
}
Controller
public function actionResults()
{
$category=$_POST['terms'];
$dataProvider=new CActiveDataProvider(
'Profile',
array(
'criteria'=>array(
'with'=>array('profile_category'),
'condition'=>'display=10 AND profile_category.category_id=1',
'order'=>'t.id DESC',
'together'=>true,
),
)
);
$this->render('results',array(
'dataProvider'=>$dataProvider,
));
}
View
<div id=resultsleft>
<?php
foreach($dataProvider as $value)
{
echo $value->profile_id;
}
?>
</div>
Any thoughts? Thank You! Nothing shows in the view.
You have to set up a property called profileCategory (not profile_category) in the profile model:
'profileCategory'=>array(
self::HAS_MANY,
'ProfileCategory',
'profile_id'
),
You can use it with an and condition as follows:
'criteria'=>array(
'with'=>array('profileCategory'),
'condition'=>'display=10 AND profileCategory.category_id=1',
'order'=>'t.id DESC',
'together'=>true,
),
It would be better for logical id first to model relation...
An example is available here.
Category model
'Profile', 'profile_category(profile_id, ...)'
public function relations()
{
return array(
'profiles'=>array(
self::MANY_MANY,
'Profile',
'profile_category(profile_id, category_id)'
),
'profile_category'=>array(
self::HAS_MANY,
'ProfileCategory',
'category_id',
),
);
}
Profile model
'Category', 'profile_category(category_id, ...)'
public function relations()
{
return array(
'categories'=>array(
self::MANY_MANY,
'Category',
'profile_category(category_id, profile_id)'
),
'profile_category'=>array(
self::HAS_MANY,
'ProfileCategory',
'profile_id'
),
);
}
Its actualy if model of database has
many self::BELONGS_TO and database has only PK (PrimaryKeys)
such code will be correctly executed
print_r(Profile::model()->findByPk(5)->categories);
print_r(Category::model()->findByPk(8)->profiles);

Categories