I'm having a model Anketa which has user_id as a primary key, not just id.
And I want to create a HAS_ONE relation for it so i code this:
function relations()
{
return array(
...
'last_experience' => array(
self::HAS_ONE, 'Experience', 'user_id',
'condition' => '
`signoff` = (
SELECT MAX( `signoff` )
FROM `experience` AS t2
WHERE t2.user_id = last_experience.user_id )
',
),
);
}
But when I try to get this property I get "Property "Anketa.id" is not defined." error.
I found some code in CActiveFinder.php file that does the following:
if($this->relation instanceof CBelongsToRelation)
{
if(is_int($i))
{
if(isset($parent->_table->foreignKeys[$fk])) // FK defined
$pk=$parent->_table->foreignKeys[$fk][1];
else if(is_array($this->_table->primaryKey)) // composite PK
$pk=$this->_table->primaryKey[$i];
else
$pk=$this->_table->primaryKey;
}
$params[$pk]=$record->$fk;
}
This block returns id for some reason instead of user_id. I don't know if it's a bug, because other relations work fine, but they're just not as complicated as this one.
Why does it happen? How can I fix this?
Thank you!
Try to leave the PK field empty and use the 'on' condition override.
function relations()
{
return array(
'last_experience' => array(
self::HAS_ONE,
'Experience',
'',
'on' => 'user_id=last_experience.user_id'
),
);
}
Related
I am trying to build a simple relation between two tables.
Unfortunately, the ORM searches for another column from the parent model:
<?php
class Model_Hreflang extends ORM {
[...]
protected $_table_columns = array(
'id' => NULL,
'domain_id' => NULL,
'country_code_id' => NULL,
'language_code_id' => NULL
);
protected $_has_many = array(
'cc' =>
array(
'model'=> 'Country2',
**'WHAT TO PUT HERE'** => 'country_code_id',
'foreign_key' => 'country_code'),
}
When trying to get a related record to the first table, the query is made like
"hreflang".id = "country2".country_code
and I need to change it, for example to
"hreflang".country_code_id = "country2".country_code
Anyone managed to do it by the ORM?
Thanks!
Anton
I think you schould set it by belongs to
protected $_belongs_to = array('cc' => array('model' => 'Country2', 'foreign_key' => 'country_code'));
read more here: http://kohanaframework.org/3.0/guide/orm/relationships
I am trying to create a form which will have multiple fields , some fields will be filled by user and others will be dump into database as defined .
I really do not know how to work with this in term of syntax.
To be more Generic , For Example I have Post tble which have following fileds
id' => 'ID',
'post_head' => 'Heading',
'post_desc' => 'Description',
'post_tags' => 'Tags',
'created_time' => 'Created Time',
'created_date' => 'Created Date',
'post_image' => 'Upload Image',
'post_status' => 'Status',
'user_id' => 'User',
'category_id' => 'Category',
);
Now I want to take input from user in the following fields only :
Heading
Description
Tags
Upload Image
Now I want to know that How can I
pass current time and current date in database field without user
input. user id from session
In your model:
function beforeSave() {
if($this->getIsNewRecord()) {
$this->created_date = new CDbExpression('NOW()');
$this->created_time = new CDbExpression('NOW()');
}
$this->user_id = Yii::app()->user->id;
return parent::beforeSave();
}
1) If the you use database like MySQL you don't need created_date and created_time, just a datetime field (probably created_time is such), which will store both data!
public function behaviors()
{
return array(
'CTimestampBehavior' => array(
'class' => 'zii.behaviors.CTimestampBehavior',
'updateAttribute' => false,
'createAttribute' => 'created_time',
)
);
}
Then for two:
function beforeSave() {
if (!parent::beforeSave) {
return false;
}
$this->user_id = Yii::app()->user->id; // it should be this one, but it depends on how you implemented logging!
return true;
}
Instead of
'created_time' => 'Created Time',
'created_date' => 'Created Date',
You need just one field in your database:
create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
Many of php functions use timestamp, it's very easy to use it. You can read here.
So if you insert NULL create_time, mysql will insert default value DEFAULT CURRENT_TIMESTAMP - current time.
As said #Veseliq and #mashingan you need to add
function beforeSave() {
$this->user_id = Yii::app()->user->id;
return parent::beforeSave();
}
or try to add in your form view:
echo $form->hiddenField($model, 'user_id', array('value'=>Yii::app()->user->id));
If it doesn't work, show us var_dump(Yii::app()->user->id);
Agent:
agent_id (primary key)
User:
f_id (foreign key)
type
I have created relation in this way
public function relations() {
return array(
'user' => array(self::HAS_ONE, 'Users', 'f_id'),
);
}
But I want to add more conditions like join only if type=3 in User table.
thanks.
There is no error like 'Property "CHasOneRelation.0" is not defined' if you use this:
public function relations()
{
return array(
'user' => array(
self::HAS_ONE,
'Users',
'f_id',
'on' => 'user.ref_type = :type',
'params' => array(':type' => 3))
);
}
See this link: http://www.yiiframework.com/forum/index.php/topic/10185-using-relations-and-conditions/
add the condition on your relation
public function relations() {
return array(
'user' => array(self::HAS_ONE, 'Users', 'f_id', array(
'condition' => 'user.type = :type',
'params' => array(':type'=>3)
)),
);
}
http://www.yiiframework.com/doc/guide/1.1/en/database.arr#relational-query-options
You should create a function to get user rather use lazy-load which would use more query even you do not use this relation.
public function getUser(){
return Users::model()->find(array(
'condition'=>'type = :type',
'params' => array(':type'=>3)
));
}
By using this you could use cache function to cache query that relation does not support.
public function getUser(){
return Users::model()->cache(1000)->find(array(
'condition'=>'type = :type',
'params' => array(':type'=>3)
));
}
I Have a GetStudents function in Agent model. where I fetch the students related to the agents.
But I want to show more fields of students from another table
Eg
**Agent table** (agent has students)
agent_id
**student table**
STUDENTID pkey
agent_id
**relation table** (this table creates relation between student and household)
StudentID HOUSEHOLDID
**HOUSEHOLD TABLE**
HouseHOLDID Householdname
I want to fetch householdname when I fetch all student details.
really looking bazzare to me as I am newbie to YII
MY function in agent model.
public static function getStudents($id) {
$relationships = Relationship::model()->findAll('type = :type AND source = :agent_id', array(':type' => 2, ':agent_id' => $id));
//$relationships=sort($relationships);
// Generate relationship array
//print_r($relationships);
foreach ($relationships as $relationship) {
$in[] = $relationship->destination;
}
// Generate db condition
$criteria = new CDbCriteria;
if (! isset($in) || ! is_array($in) || sizeOf($in) == 0) {
$in[] = -999;
}
$criteria->addInCondition('StudentID', $in, 'OR');
return new CActiveDataProvider('Student', array(
'criteria' => $criteria,
'sort'=>array('defaultOrder'=>array(
'StudentID'=>CSort::SORT_DESC,
)),
));
}
My code to fetch data in by passing ID into it
<?php $this->widget('zii.widgets.CDetailView', array(
'data' => $model,
'attributes' => array(
array(
'label' => 'Agent Details',
'type' => 'raw',
'value' => '',
'cssClass' => 'heading',
),
'agent_id',
'user.email',
'first_name',
'last_name',
'company',
'phone',
),
)); ?>
Any help would be greatly appreicated.
Thanks
Ab
First you should make relation with student to relation table in relations array in relation model like this ..
'student'=>array(self::BELONGS_TO, 'Student', 'StudentID'), //after belongs to student is model class name
'household'=>array(self::BELONGS_TO, 'HOUSEHOLD', 'HOUSEHOLDID'),//after belongs to HOUSEHOLD is model class name
And then you can fetch all record with active record like this...
$relationships = Relationship::model()->with('student','household')->findAll('type = :type AND source = :agent_id', array(':type' => 2, ':agent_id' => $id));
I'm trying to use Lithiums list option with find() along with SQL's DISTINCT.
I should get an array populated with values, instead, I'm getting an empty array.
This does make sense since I'm passing in the distinct fields as one string instead of an array of elements but I don't know how else to use DISTINCT in Lithium.
Some direction would be greatly appreciated.
It may be valentines day but Lithium is not showing me too much love today :)
Model:
class ZipCodes extends \app\extensions\data\Model {
protected $_meta = array(
'key' => 'zip_code_id',
'title' => 'state_name'
);
protected $_schema = array(
'state_name' => array('type' => 'varchar'),
'StateFIPS' => array('type' => 'varchar')
//there are more fields in my table but I haven't defined the
//rest in my model
);
}
The add method in my controller
public function add()
{
$zipcodes = Zipcodes::find('list', array(
'fields' => array('DISTINCT state_name'),
'order' => 'state_name ASC',
'conditions' => array('state_name' => array('!=' => ''))
)
);
return compact('zipcodes');
}