PDA

View Full Version : یک CDbCriteria نسبتا پیچیده



p30tec
دوشنبه 06 خرداد 1392, 09:37 صبح
سلام دوستان و استاید محترم
من توی این تاپیک سوالی رو مطرح کردم و جوابش رو گرفتم
http://barnamenevis.org/showthread.php?400270-%DA%A9%D9%85%DA%A9-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%86-%D8%AF%D8%B1%D8%A8%D8%A7%D8%B1%D9%87-%DB%8C%DA%A9-%DA%A9%D9%88%D8%A6%D8%B1%DB%8C-%D9%86%D8%B3%D8%A8%D8%AA%D8%A7-%D9%BE%DB%8C%DA%86%DB%8C%D8%AF%D9%87&p=1777577

دوستان کسی میدونه چطوری میشه
SELECT *
FROM (
SELECT *
FROM `tbl_log`
ORDER BY logtime DESC
) `t1`
GROUP BY `post_id
رو به CDbCriteria تبدیل کرد ؟؟

یا اصلا بزارید توضیح بدم چی میخوام؟؟ شاید راه بهتری باشه
ببینید مثال ساده کار من این میشه
فرض کنید توی یه بلاگ هر پستی که تغییر میکنه توی یه جدول لاگ ، اطلاعاتی مثل وضعیت جدید پست و زمان تغییر پست و ... ثبت میشه یعنی اگه برای یه پست ده تا لاگ داریم جدید ترین لاگ نشون میده آخرین وضعیت پست چیه و اگه وضعیت های قدیمی هم خواستیم داریم
من به هر دو وضعیت قدیم و جدید نیاز دارم اما چون وضعیت جدید خیلی بیشتر نیاز میشه و باید توش سرچ هم بشه من این کار رو کردم



<?php
/**
* @return array relational rules.
*/
public function relations()
{
return array(
..............
'postLogs' => array(self::HAS_MANY, 'PostLog', 'post_id'),
'neweststatus'=> array(self::HAS_ONE, 'PostLog', 'post_id',
'order'=>'neweststatus.regtime DESC',
),
..............
);
}
?>


یعنی دو ارتباط postLogs که یک به چنده و neweststatus یه یک به یک هست رو تعریف کردم

حالا به راحتی میشه به آخرین وضعیت این طوری دسترسی داشت



<?php
$post->neweststatus->status;//Status ID
$post->neweststatus->log_time;//When Status changed to this status
?>

اما فرض کنید فقط پست هایی که آخرین وضعیتشون 1 و 2 هست برای کاربر نهایی باید دیده بشن و بقیه مخفی هستند بنابراین من یه Name Scope ساختم اینطوری





<?
public function userVisible()//Only Visible Post for end-users
{
$criteria = new CDbCriteria;
$criteria->with = array('neweststatus');
$criteria->addColumnCondition(
array(
'neweststatus.status' => 1,
'neweststatus.status' => 0,
),
'OR'
);
$this->getDbCriteria()->mergeWith($criteria);
return $this;
}
?>

مشکل اینجاست که این Name Scope میاد و پست هایی که دست کم وضعیت 1 یا 0 را دارند میاره یعنی چی ؟؟ اینو ببینید




ID = 1
Status = 0
Log_Time = 2013-01-01
Post_ID = 1

ID = 2
Status = 1
Log_Time = 2013-01-02
Post_ID = 1

ID = 3
Status = 2
Log_Time = 2013-01-03
Post_ID = 1




اگه ببنید پست یک توی رکورد های مختلف Status مختلفی داره و با اینکه جدید ترین Status مساوی 2 هست اما Status های قدیمی 0 و 1 هستند و بنابراین اشتباهی این name scope پست یک رو که وضعیت فعلی اون 2 هست رو هم میاره

من میدونم با این کوئری
SELECT *
FROM (
SELECT *
FROM `tbl_log`
ORDER BY logtime DESC
) `t1`
GROUP BY `post_id
وضعیت های هر پست دقیقا و درست نشون داده میشه اگه دوباره Relation ها رو ببینید توی neweststatus همه وضعیت ها به تریب جدید به قدیم مرتب میشن و اولی به دلیل Has_ONE برداشته میشه اما توی Name Scope همه میان و تاثیر میزارند


من فکر کنم در عین پیچیدگی قضیه جواب ساده باشه کسی نظری داره ؟؟ لطفا کمک کنید

p30tec
سه شنبه 07 خرداد 1392, 12:47 عصر
مشکل رو به نحوی حل کردم