Yii extract values after using Has_Many relation - yii

Relation:
'attendances' => array(self::HAS_MANY, 'Attendance', 'atd_atbs_Id')
Controller:
$report=AtbStud::model()->with('attendances')->findAll('atbs_atb_Id='.$id);
foreach ($report->attendances as $value) {
echo Yii::trace(CVarDumper::dumpAsString($value->atd_Date),'vardump');;
}
Error:
"$report->attendances" Trying to get property of non-object.
How can we access values wen we use has_many relation.

Related

Yii: use STAT relation as parameter for another relation's condition

Is possible in Yii 1.1.14 use a STAT relation as parameter in the condition of another relation of the same model??
public function relations()
{
return array(
'attivita' => array(self::BELONGS_TO, 'Attivita', 'attivita_id'),
'totLezioni'=>array(self::STAT, 'LezioniSettimanali', 'corso_id'),
'tariffe'=>array(self::HAS_MANY,'Tariffe',array('id'=>'attivita_id'),'through'=>'attivita','condition' => 'tariffe.tipo=:tc OR tariffe.freqSettimanale = :totLezioni','params' => array(':tc'=>'I',':totLezioni'=>$this->totLezioni)),
);
}
Error: "Corsi"."totLezioni" not defined.

kohana ORM - add new record for has_many, has_one relationships

Kohana ORM has the following relationships between model:
has_one
has_many
has_many_through
For example, I have the following defined:
class Model_ORM_Text extends ORM {
protected $_has_one = array(
'compiledData' => array('model' => 'CompiledText', 'foreign_key' => 'idText'),
);
protected $_has_many = array(
'translations' => array('model' => 'TextTranslation', 'foreign_key' => 'idText')
);
protected $_has_many_through = array(
'tags' => array('model' => 'TextTranslation', 'through' => 'rl_text_tags')
);
}
I need to create a new related model for each of these relationships. I've only found the add method in ORM class that allows adding related model that is linked through has_many_through relationships, like this:
$text->add("tags", $tagId);
But I can't find anywhere how I can add a related model for the has_one and simple has_many relationships. Is it possible?
The key to the question is that on the "other" side of every has_many and has_one is a belongs_to. And this is the model where the information is saved.
In your case Model_CompiledText has the column idText (under a specific alias). To (un)set the relationship, you need to manipulate this field. Say you have a belongs_to in there under the name text, this is how you would do it:
$compiledText = ORM::factory('CompiledText');
// set text
// Version 1
$compiledText->text = ORM::factory('Text', $specificId);
// Version 2
$compiledText->text = ORM::factory('Text')->where('specificColumn', '=', 'specificValue')
->find();
// unset text
$compiledText->text = null
// save
$compiledText->save();
In the case of a has_one you can access it directly via the parent and so do
$text->compiledData->text = ...;

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!

CGridview and Yii Active Record Relation

I have two tables tbl_business and business_contacts of the following structure:
tbl_business
---
business_id (PK)
othercolumns
and
business_contacts
---
contact_id (PK)
business_id
othercolumns
The scenario is that one business row has many contacts. I am using cGridview using gii's CRUD generator and needed to display firstname and lastname from business_contacts (one of multiple possible rows in the table) for each tbl_business record.
As far as I understand, I've updated the relation function in tbl_business's model as:
'businesscontacts' => array(self::HAS_MANY,'BusinessContact','business_id','select' => 'contact_firstname, contact_lastname')
and for the same, a contact relation is defined in the business_contacts' model as:
'contactbusiness' => array(self::BELONGS_TO,'BusinessContact','business_id')
I expected that would work for pulling related records so that I can have something in the grid like, business_id, contact_firstname, contact_lastname , ... otherbusinesstablecolumns .. but I'm only getting blank values under firstname and lastname .. could someone please help me understand the error? :(
So you are trying to display a table of Businesses (tbl_business) using CGridView? And in each Business's row you want to list multiple Contacts (business_contacts)?
CGridView does not support displaying HAS_MANY relations by default. CGridView makes it easy to list which Business a Contact BELONGS_TO (i.e. you can use a column name like contactbusiness.business_id), but not all of the Contacts that are in a business.
You can do it yourself though, by customizing a CDataColumn. (Note: this will not allow you to sort and filter the column, just view. You'll have to do a lot more work in to get those working.)
First, in your Business model, add a method like this to print out all of the contacts:
public function contactsToString() {
$return = '';
foreach ($this->businesscontacts as $contact) {
$return .= $contact->contact_firstname.' '.$contact->contact_firstname.'<br />';
}
return $return;
}
(EDIT: Or do this to print out just the first contact):
public function contactsToString() {
if($firstContact = array_shift($this->businesscontacts)) {
return $firstContact->contact_firstname.' '.$firstContact->contact_firstname;
}
return '';
}
Then make a new column in your grid and fill it with this data like so:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'business-grid',
'dataProvider'=>$model->yourDataProviderFunction(),
'columns'=>
'business_id',
array(
'header'=>'Business Contacts', // give new column a header
'type'=>'HTML', // set it to manual HTML
'value'=>'$data->contactsToString()' // here is where you call the new function
),
// other columns
)); ?>
EDIT2: Yet another way of doing this, if you just want to print out ONE of a HAS_MANY relation, would be to set up a new (additional) HAS_ONE relation for the same table:
public function relations()
{
return array(
'businesscontacts' => array(self::HAS_MANY,'BusinessContact','business_id','select' => 'contact_firstname, contact_lastname') // original
'firstBusinesscontact' => array(self::HAS_ONE, 'BusinessContact', 'business_id'), // the new relation
);
}
Then, in your CGridView you can just set up a column like so:
'columns'=>array(
'firstBusinesscontact.contact_firstname',
),
Getting only the first contact could be achieved like this also:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'business-grid',
'dataProvider'=>$model->yourDataProviderFunction(),
'columns'=>
'business_id',
//....
array(
'name' => 'contacts.contact_firstname',
'value' => '$data->contacts[0]->contact_firstname', // <------------------------
'type' => 'raw'
);
//....
),

Kohana ORM: Get results based on value of a foreign table

taxonomies
-id
-name
taxonomy_type
-taxonomy_id
-type_id
I've configured two models:
class Model_Taxonomy{
protected $_has_many = array('types'=>array());
}
class Model_Taxonomy_Type{
protected $_belongs_to = array('taxonomy' => array());
}
*Please note that taxonomy_type is not a pivot table.*
A taxonomy can have multiple types associated.
Then, what I'm trying to do is get all taxonomies that belong to a given type id.
This is would be the SQL query I would execute:
SELECT * FROM taxonomies, taxonomy_type WHERE taxonomy_type.type_id='X' AND taxonomies.id=taxonomy_type.taxonomy_id
I've tried this:
$taxonomies = ORM::factory('taxonomy')
->where('type_id','=',$type_id)
->find_all();
Obviously this doesn't work, but I can't find info about how execute this kind of queries so I have no clue.
class Model_Taxonomy{
protected $_belongs_to = array(
'types' => array(
'model' => 'Taxonomy_Type',
'foreign_key' => 'taxonomy_id'
)
);
}
class Model_Taxonomy_Type{
protected $_has_many = array(
'taxonomies' => array(
'model' => 'Taxonomy',
'foreign_key' => 'taxonomy_id'
)
);
}
And use some like that:
$type = ORM::factory('taxonomy_type')
->where('type_id', '=', $type_id)
->find();
if( ! $type->taxonomies->loaded())
{
types->taxonomies->find_all();
}
type_id column is a PK of taxonomy_type table, am I right?
So, you have one (unique) taxonomy_type record, and only one related taxonomy object (because of belongs_to relationship). Instead of your:
get all taxonomies that belong to a
given type id
it will be a
get taxonomy for a given type id