Add sorting on joined model virtual field, fixes #2250

This commit is contained in:
Ceeram 2011-11-14 01:34:49 +01:00
parent 3cb5188b2d
commit e5c8a446d6
4 changed files with 120 additions and 2 deletions

View file

@ -353,7 +353,7 @@ class PaginatorComponent extends Component {
$order[$alias . '.' . $field] = $value;
} elseif ($object->hasField($key, true)) {
$order[$field] = $value;
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field)) {
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
$order[$alias . '.' . $field] = $value;
}
}

View file

@ -2590,6 +2590,10 @@ class DboSource extends DataSource {
if (is_object($model) && $model->isVirtualField($key)) {
$key = '(' . $this->_quoteFields($model->getVirtualField($key)) . ')';
}
list($alias, $field) = pluginSplit($key);
if (is_object($model) && $alias !== $model->alias && is_object($model->{$alias}) && $model->{$alias}->isVirtualField($key)) {
$key = '(' . $this->_quoteFields($model->{$alias}->getVirtualField($key)) . ')';
}
if (strpos($key, '.')) {
$key = preg_replace_callback('/([a-zA-Z0-9_-]{1,})\\.([a-zA-Z0-9_-]{1,})/', array(&$this, '_quoteMatchedField'), $key);

View file

@ -87,6 +87,13 @@ class PaginatorControllerPost extends CakeTestModel {
*/
public $lastQueries = array();
/**
* belongsTo property
*
* @var array
*/
public $belongsTo = array('PaginatorAuthor' => array('foreignKey' => 'author_id'));
/**
* beforeFind method
*
@ -183,6 +190,45 @@ class PaginatorControllerComment extends CakeTestModel {
public $alias = 'PaginatorControllerComment';
}
/**
* PaginatorAuthorclass
*
* @package Cake.Test.Case.Controller.Component
*/
class PaginatorAuthor extends CakeTestModel {
/**
* name property
*
* @var string 'PaginatorAuthor'
*/
public $name = 'PaginatorAuthor';
/**
* useTable property
*
* @var string 'authors'
*/
public $useTable = 'authors';
/**
* alias property
*
* @var string 'PaginatorAuthor'
*/
public $alias = 'PaginatorAuthor';
/**
* alias property
*
* @var string 'PaginatorAuthor'
*/
public $virtualFields = array(
'joined_offset' => 'PaginatorAuthor.id + 1'
);
}
class PaginatorComponentTest extends CakeTestCase {
/**
@ -190,7 +236,7 @@ class PaginatorComponentTest extends CakeTestCase {
*
* @var array
*/
public $fixtures = array('core.post', 'core.comment');
public $fixtures = array('core.post', 'core.comment', 'core.author');
/**
* setup
@ -490,6 +536,30 @@ class PaginatorComponentTest extends CakeTestCase {
$this->assertEqual(Set::extract($result, '{n}.PaginatorControllerPost.offset_test'), array(2, 3, 4));
}
/**
* test paginate() and virtualField on joined model
*
* @return void
*/
public function testPaginateOrderVirtualFieldJoinedModel() {
$Controller = new PaginatorTestController($this->request);
$Controller->uses = array('PaginatorControllerPost');
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->PaginatorControllerPost->recursive = 0;
$Controller->Paginator->settings = array(
'order' => array('PaginatorAuthor.joined_offset' => 'DESC'),
'maxLimit' => 10,
'paramType' => 'named'
);
$result = $Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertEqual(Set::extract($result, '{n}.PaginatorAuthor.joined_offset'), array(4, 2, 2));
$Controller->request->params['named'] = array('sort' => 'PaginatorAuthor.joined_offset', 'direction' => 'asc');
$result = $Controller->Paginator->paginate('PaginatorControllerPost');
$this->assertEqual(Set::extract($result, '{n}.PaginatorAuthor.joined_offset'), array(2, 2, 4));
}
/**
* Tests for missing models
*

View file

@ -7543,6 +7543,50 @@ class ModelReadTest extends BaseModelTest {
$this->assertEqual($result, 4);
}
/**
* testVirtualFieldsOrder()
*
* Test correct order on virtual fields
*
* @return void
*/
public function testVirtualFieldsOrder() {
$this->loadFixtures('Post', 'Author');
$Post = ClassRegistry::init('Post');
$Post->virtualFields = array('other_field' => '10 - Post.id');
$result = $Post->find('list', array('order' => array('Post.other_field' => 'ASC')));
$expected = array(
'3' => 'Third Post',
'2' => 'Second Post',
'1' => 'First Post'
);
$this->assertEqual($result, $expected);
$result = $Post->find('list', array('order' => array('Post.other_field' => 'DESC')));
$expected = array(
'1' => 'First Post',
'2' => 'Second Post',
'3' => 'Third Post'
);
$this->assertEqual($result, $expected);
$Post->Author->virtualFields = array('joined' => 'Post.id * Author.id');
$result = $Post->find('all');
$result = Set::extract('{n}.Author.joined', $result);
$expected = array(1, 6, 3);
$this->assertEqual($result, $expected);
$result = $Post->find('all', array('order' => array('Author.joined' => 'ASC')));
$result = Set::extract('{n}.Author.joined', $result);
$expected = array(1, 3, 6);
$this->assertEqual($result, $expected);
$result = $Post->find('all', array('order' => array('Author.joined' => 'DESC')));
$result = Set::extract('{n}.Author.joined', $result);
$expected = array(6, 3, 1);
$this->assertEqual($result, $expected);
}
/**
* testVirtualFieldsMysql()
*