I am writing a function to get posts and ordered by the number of likes.
I can do it fine in pure SQL, but I wanted to have it written in the yii way.
Here is what I have so far:
public static function getPopularPosts($limit) {
$posts = Tip::model()
->with( array(
'Like' => array(
'select' => 'sum(`Like`.value) as likes',
'join' => 'LEFT JOIN `Like` ON `Tip`.idTip = `Like`.relatedTableIdFK',
'condition'=>'`Like`.relatedTableName like "Tip" AND `Like`.status=1',
)));
$posts ->together();
$posts ->findAll(array(
'group'=>'idTip',
'order'=>'likes DESC',
'limit' => $limit,
));
return $posts;
}
And the get the error:
Relation "Like" is not defined in active record class "Tip".
Read first please http://www.yiiframework.com/doc/guide/1.1/en/database.arr#declaring-relationship
Then open your model Tip find method relations or create new and add there relation according to documentation above.
public function relations(){
return array(
'Like'=>array(self::HAS_MANY, 'Like', 'relatedTableIdFK')
);
}
Related
I have a model Order with one-to-many relationship to model Booking. Booking model, in turn, has a Connection model reference.
I'm having trouble figuring out how to scope out Order so that I only get the order that have bookings with Connection.isDefault value set to 0.
I may have many Bookings with the Order, so I need to look through the very first booking.
I feel this may not be achievable through the scope mechanism as I cannot pass Order/Booking primary keys through helper functions that can be used in scope. What is an alternative workaround here (if any) can you suggest?
The Order has a code for scopes:
public function scopes()
{
return array(
'canView' => array(
'with' => array(
'agency' => array(
'scopes' => array('myNetwork', 'myCompany' => 'OR')
)
),
),
'canEdit' => array(
'with' => array(
'agency' => array(
'scopes' => array('myNetwork', 'myCompany' => 'OR')
),
),
),
);
}
Please try using CDbCriteria(). add relation in Bookings table and order table.
The Bookings has a code for relation:
class Bookings extends CActiveRecord{
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(
'connectionRel' => array(self::BELONGS_TO, 'connection', 'booking_id', "condition" => 'isDefault = 0'),
);
}
}
The Order has a code for relation:
class Order extends CActiveRecord{
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(
'bookingsRel' => array(self::BELONGS_TO, 'Bookings', 'booking_id', "with" => array('connectionRel')),
);
}
}
Find all order with booking relation :
Order::model()->with('bookingsRel')->findAll();
Try using CDbCriteria(). In with you can put relation and it there do again with (do some CDbCriteriaCeption). Try experimenting with other criteria params to fit your needs (like applying $c->together = true;)
$c = new CDbCriteria();
$c->with = [
'bookings' => [
'select' => false,
'with' => [
'connections' => [
'select' => false,
]
]
]
];
$c->addCondition('connections.isDefault = 0');
Order::model()->findAll($c);
How would i add a 3rd relation to my relations() function to join the CommentsPosts model with the store model. Where CommentsPosts.store_id = Store.id and CommentsPosts.store_zip = Store.zip?
in my comment.php
public function relations()
{
return array(
'user' => array(self::BELONGS_TO, $this->module->userModelClass, 'userId'),
'posts' => array(self::HAS_MANY, "CommentsPosts", array("commentId" => "id")),
'store'=>'',
);
}
CommentsPost.php is in modules/comments/model and Store.php is in modules/store/model
FYI, i'm using Yii 1.1.15
I'm not sure about your relations but try something like bellow
In Comment post Model add the relation
public function relations()
{
return array(
'store' => array(self::HAS_MANY, "Store", array("store_id" => "id")),
);
}
When retrieving
$enity->post // give all post
$enity->post[i]->store // gives the each post data of store
I have a problem regarding the use of CDbCriteria in a controller index action. I have 2 classes: event and attendee.
the class event has many attendee, and i want my event index action to render only the list of events of which the current loggedin user is an attendee...
$criteria = new CDbCriteria(array(
'order'=>'event_date desc',
'with' => array('attendees'=>array('alias'=>'attend')),
'condition'=>'attend.uid = ' . Yii::app()->user->id,
));
$dataProviderAtt=new CActiveDataProvider('Event',
array(
'criteria' => $criteria,
)
);
$this->render('index',array(
'dataProvider'=>$dataProviderAtt,
));
this does not work in DB with the message:
CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'user'
my relations in attendee class are set like this:
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(
'user' => array(self::BELONGS_TO, 'YumProfile', 'uid', 'alias'=>'user'),
);
}
I tried to change the defaultscope in attendee model and define multiple aliases:
public function defaultScope()
{
static $counter = 0;
return array(
'with' => array('user'=>array('alias'=>'user'.($counter++))),
//'with' => 'user',
'order' => 'score DESC',
);
}
but it does not seem to fix the issue and I then have more errors. Is my criteria correctly set?
Thx guys for your help
you are looking for
'on' => 'attend.uid = ' . Yii::app()->user->id,
as in your relation to the user
function relations()
{
return array(
'user' => array(
self::BELONGS_TO,
'attendees',
'',
'on' => 'attendees.uid = ' . Yii::app()->user->id,
),
);
}
There is a comprehensive article about searching and sorting by related model in CGridView here: http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview/ I've successfully implemented this recipe a number of times.
However, now I am trying to search and sort by a relation that is in the same table (it defines the parent_id). See 'parent' relation below:
public function relations()
{
return array(
'parent' => array(self::BELONGS_TO, 'Category', 'parent_id'),
'children' => array(self::HAS_MANY, 'Category', 'parent_id'),
'childCount' => array(self::STAT, 'Category', 'parent_id'),
'author0' => array(self::BELONGS_TO, 'User', 'author'),
'contents' => array(self::MANY_MANY, 'Content', 'content_category(content_id, category_id)'),
'crsContents' => array(self::MANY_MANY, 'ContentCrs', 'content_category(content_id, category_id)'),
);
}
public function defaultScope()
{
return array(
'alias'=>'cat',
'order'=>"cat.name ASC",
);
}
When I implement the method as specified by the wiki, I get the following error:
CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'cat'. The SQL statement executed was: SELECT COUNT(DISTINCT `cat`.`id`) FROM `category` `cat` LEFT OUTER JOIN `category` `cat` ON (`cat`.`parent_id`=`cat`.`id`) WHERE (cat.parent_id <> 257)
How can I ensure that the LEFT OUTER JOIN uses a unique table alias such as parent for the relation so that I can properly define my CDbCriteria in search()
EDIT:
As requested by #tereško, here is my search() function. I know it is flawed due to the table alias parent specified when I have not defined it... I just don't know how!
public function search()
{
$criteria=new CDbCriteria;
$criteria->with = array('parent');
$criteria->compare('id',$this->id,true);
$criteria->compare('author',$this->author,true);
$criteria->compare('name',$this->name,true);
$criteria->compare('description',$this->description,true);
$criteria->compare('parent_id',$this->parent_id,true);
$criteria->compare('parent.name', $this->parent_search, true );
$criteria->compare('type',$this->type,true);
$criteria->compare('slug',$this->slug,true);
$criteria->compare('created',$this->created,true);
$criteria->compare('updated',$this->updated,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'sort'=>array(
'attributes'=>array(
'parent_search'=>array(
'asc'=>'parent.name',
'desc'=>'parent.name DESC',
),
'*',
),
),
)
);
}
You can give alias to parent relation as below
$criteria->with = array(
'parent'=>array(
'alias'=>'parent'
)
);
I have a strange problem with my yii application. I have two tables in my database Players - id, name, team_id and Teams - id, name. I can create new players but when I want to see player's profile there is an error -"Trying to get property of non-object" at this line:
'value'=>$model->team->NAME,
The most strange problem is that when I test url for players with Ids 1 and 2 everything is okay and I see the correct information, but for other ids I have this problem. Here is part of my code:
view.php
<?php $this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'ID',
'NAME',
'TEAM_ID',
array(
'label'=>'Отбор',
'type'=>'text',
'value'=>$model->team->NAME,
),
),
)); ?>
Players.php
public function relations()
return array(
'team' => array(self::BELONGS_TO, 'TEAMS', 'ID'),
);
}
Teams.php
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(
'player' => array(self::HAS_MANY, 'PLAYERS', 'ID'),
);
}
PlayersController.php
public function actionView($id)
{
$teams = new CActiveDataProvider('Teams');
$players = new CActiveDataProvider('Players');
$this->render('view', array(
'model'=>$this->loadModel($id),
));
}
Seems like you need to fix bug with relations in Players model:
public function relations()
return array(
'team' => array(self::BELONGS_TO, 'TEAMS', 'TEAM_ID'), // TEAM_ID instead of ID
);
}