Using STAT relation in CActiveDataProvider criteria - yii

This is my controller action
public function actionIndex()
{
//Supervisor non possono vedere brani OPEN
//Gerard (manager) non puo' vedere OPEN/REJECTED/PROPOSED/CLOSED
//Editor non puo' vedere APERTO/PROPOSTO/REJECTED se non suo
$with = array(
'propostoCount',
'pubblicatoCount',
'pendingCount',
'apertoCount',
'rifiutatoCount',
'chiusiCount',
);
$condition = 'propostoCount=1 AND pubblicatoCount=1 AND pendingCount=1 AND rifiutatoCount=1 AND chiusiCount>0';
$dataProvider=new CActiveDataProvider('Brano', array(
'criteria'=>array(
'with'=>$with,
'condition'=>$condition,
'order'=>'id DESC',
),
'pagination'=>array(
'pageSize'=>5,
),
));
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
}
And these are my relations in Brano 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(
'proposto' => array(self::HAS_ONE, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_PROPOSED, 'order'=>'ultimo_aggiornamento DESC'),
'pubblicato' => array(self::HAS_ONE, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_PUBLISHED, 'order'=>'ultimo_aggiornamento DESC'),
'pending' => array(self::HAS_ONE, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_PENDING, 'order'=>'ultimo_aggiornamento DESC'),
'aperto' => array(self::HAS_ONE, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_OPEN, 'order'=>'ultimo_aggiornamento DESC'),
'rifiutato' => array(self::HAS_ONE, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_REJECTED, 'order'=>'ultimo_aggiornamento DESC'),
'chiusi' => array(self::HAS_MANY, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_CLOSED, 'order'=>'ultimo_aggiornamento DESC'),
'propostoCount'=>array(self::STAT, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_PROPOSED ),
'pubblicatoCount'=>array(self::STAT, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_PUBLISHED ),
'pendingCount'=>array(self::STAT, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_PENDING ),
'apertoCount'=>array(self::STAT, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_OPEN ),
'rifiutatoCount'=>array(self::STAT, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_REJECTED ),
'chiusiCount'=>array(self::STAT, 'BranoVersione', 'brano_id', 'condition'=>'stato='.BranoVersione::STATUS_CLOSED ),
);
}
When I try to run it it says:
CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'propostoCount' in 'where clause'. The SQL statement executed was: SELECT COUNT(DISTINCT t.id) FROM brano t WHERE (propostoCount=1 AND pubblicatoCount=1 AND pendingCount=1 AND rifiutatoCount=1 AND chiusiCount>0)

I can see what you're trying to do here, compare the STAT relations value in the query right?
I ran into this same issue, but STAT relations aren't implemented that way. They're pulled from the database in a seperate query so are only available for use within PHP not in the SQL itself.
If you want to have a condition using the STAT relationship, you'll have to redefine it inside the query as a full sub-select (or something depending on the query type).

Related

Collect data from three table in yii1?

I am new in YII1. I have three tables: Jd, jda and user. Relation with jd and jda is
'jobDescription'=> array(self::HAS_MANY, 'JobDescriptionAssignment', /*array('id'=>'job_desc_id')*/'id'),
and the relation between jda and user is
'users' => array(self::BELONGS_TO, 'User', 'user_id'),
My tables are :
jd->id,name
jda->id,jd_id,user_id
user->id,supervisor_id
supervisor_id comes from user table id. Now I want to show data from jd model those user whose supervisor_id is logged in id.
see this topic Yii Framework : Join table (or other SQL) in data provider?
public function search(){
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('status',$this->status,true);
$criteria->compare('createDate',$this->createDate,true);
$criteria->compare('updateDate',$this->updateDate,true);
$criteria->compare('remark',$this->remark,true);
$criteria->with = array('cateLang' => array(
'condition' => 'cateLang.id = 1 OR cateLang.id = 2',
'order' => 'cateLang.id ASC'
));
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
-
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'category-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
array(
'name' => 'FrenchTitle'
'value' => '(isset($data->cateLang[0])) ? $data->cateLang[0]->name : "no Title"',
),
array(
'name' => 'EnglishTitle'
'value' => '(isset($data->cateLang[1])) ? $data->cateLang[1]->name : "no Title"',
),
'createDate',
'updateDate',
'remark',
array(
'class'=>'CButtonColumn',
),
),
));

How to enable eager loading on a association in phpactiverecord?

I have an phpactiverecord Model "Category". This Model has a self-referential has_many association, and two has_one associations to another Model.
class Category extends Model {
static $table_name = 'categories';
static $has_many = array(
array(
'child_categories',
'class_name' => 'Category',
'primary_key' => 'categories_id',
'foreign_key' => 'parent_id'
)
);
static $has_one = array(
array(
'german_description',
'class_name' => 'CategoryDescription',
'primary_key' => 'categories_id',
'foreign_key' => 'categories_id',
'conditions' => 'language_id = 2'
),
array(
'english_description',
'class_name' => 'CategoryDescription',
'primary_key' => 'categories_id',
'foreign_key' => 'categories_id',
'conditions' => 'language_id = 1'
)
);
}
I can eager-load the has_one associations when I find Category, this works without any problem:
$category = ActiveRecord\Category::find(
$category_id,
array(
'include' => array( 'german_description', 'english_description' )
)
);
My problem is: When I iterate through all of a category's child-categories, and access the child-categories' has-one associations...
foreach( $category->child_categories as $child_category ){
echo $child_category->german_description->categories_name;
}
..then a new query is run every time I do so, becauce the child-category's has-one associations are not eager loaded.
My question is: Is it possible to configure access a categories child-categories in a way that eager-loads the child-categories' has-one associations?

try to implement the join query in Cakephp

i am working on a cakephp and try to implement the join . or inner join query ... what i am doing right now is this
$this->bindModel(array(
'belongsTo' => array(
'Contact' => array(
'className' => 'Contact',
'foreignKey' => false,
'conditions' => array(
'Message.user_id = Contact.user_id',
'Message.mobileNo = Contact.mobileNo'
)
)
)
), false);
return $message_details = $this->find('all', array(
'conditions' => array(),
'fields' => array('DISTINCT mobileNo')
));
this query is doing LEFT JOIN the table .. what i want is join or inner join between two tables
You can specify the type of join in your belongsTo configuration, as stated in the documentation. The default is left, but you can use any valid join type. Simply add 'type' => 'inner' to the configuration array, so you should get something like this:
$this->bindModel(array(
'belongsTo' => array(
'Contact' => array(
'className' => 'Contact',
'foreignKey' => false,
'conditions' => array(
'Message.user_id = Contact.user_id',
'Message.mobileNo = Contact.mobileNo'
),
'type' => 'inner' // Simply add this
)
)
), false);
Alternatively, you can add the joins to your query without using bingModel:
return $message_details = $this->find('all', array(
'conditions' => array(),
'fields' => array('DISTINCT mobileNo'),
'joins'=>array(
array(
'table'=>'contacts,
'alias'=>'Contact',
'type'=>'INNER',
'conditions'=>array(
'Message.user_id = Contact.user_id',
'Message.mobileNo = Contact.mobileNo'
)
)
)
));

How to use CakePHP to do a query bounded by data in two indirectly-related tables

Presume the Query works:
SELECT
users.id,
subscriptions.name,
users.user_type
FROM users
LEFT JOIN users_subscriptions
ON users.id = users_subscriptions.user_id
LEFT JOIN subscriptions
ON users_subscriptions.subscription_id = subscriptions.id
WHERE
subscriptions.name = 'advertisers'
AND
users.user_type = 'agent';
How do I do this in a single Query using cakePHP 1.3?
EDIT: Are joins the right approach?
Yes joins are just fine. Just make sure that you add on the fly before searching to your User model a hasOne to UsersSubscription and to the UsersSubscription model as belongsTo Subscription. Then use the containable behavior to include 'UserSubscription' => 'Susbcription'
Your code might look like this:
$this->User->bindModel(array('hasOne' => array('UserSubscription')));
$this->User->UserSubscription->bindModel(array('belongsTo' => array('Subscription')));
$results = $this->User->find('all', array(
'contain' => array(
'UserSubscription' => 'Subscription'
)
));
You can set up the query the "CakePHP way" like this:
$conditions = array(
'Subscriptions.name' => 'advertisers',
'Users.user_type' => 'agent'
);
$joins = array(
array(
'table' => 'users_subscriptions',
'alias' => 'UsersSubscriptions',
'type' => 'LEFT',
'conditions' => array(
'UsersSubscriptions.user_id=Users.id'
)
),
array(
'table' => 'subscriptions',
'alias' => 'Subscriptions',
'type' => 'LEFT',
'conditions' => array(
'Subscriptions.id=UsersSubscriptions.subscription_id'
)
)
);
$fields = array(
'Users.id', 'Users.user_type', 'Subscriptions.name'
);
$options = array(
'conditions' => $conditions,
'joins' => $joins,
'fields' => $fields
);
$results = $this->Users->find('all', $options);

How do I set order by field when using fuelphp orm's has many?

I'm using fuelphp's orm to model my data. How can I control which order my child elements are returned when doing a cascaded find.
For example, here's the example config to attach comments to a post:
protected static $_has_many = array(
'comments' => array(
'key_from' => 'id',
'model_to' => 'Model_Comment',
'key_to' => 'post_id',
'cascade_save' => true,
'cascade_delete' => false,
)
);
How can I say, for example, order the comments by the 'date_entered' field?
Thanks in advance,
David
You can add the order_by clause to the conditions.
protected static $_has_many = array(
'comments' => array(
'key_from' => 'id',
'model_to' => 'Model_Comment',
'key_to' => 'post_id',
'cascade_save' => true,
'cascade_delete' => false,
'conditions' => array(
'order_by' => array(
'field1' => 'DESC',
'field2' => 'ASC',
)
),
),
);
Note that as they are defined in the relation, they are always active and can not be turned off!