2009-07-29 34 views
0

我无法让它工作。我使用这个查询:为什么不是Rose :: DB :: Object sort_by RAND()做我期望的事情?

my $user_questions 
    = RoseDB::UserSecurityQuestion::Manager->get_user_security_questions(
     query  => [ 
          'user.username' => $username, 
         ], 
     with_objects => ['User','SecurityQuestion'], 
     sort_by  => 'RAND()', 
     limit  => 2, 
    ); 

当我打开玫瑰:DB:对象::经理调试,我看到的是,为了条款是:

ORDER BY t1.id, RAND() 

那是哪里t1.id来自(哪里?任何想法如何我可以纠正ORDER BY只是RAND()

回答

3

documentation for the sort_by parameter

如果选择子对象(通过require_objects或with_objects),它们通过“一对多”相关或“多对多”的关系,排序顺序子句中的第一个条件必须是主表中的一列(t1)。如果不符合此条件,主键列的列表将自动添加到排序顺序子句的开头。

这是正确关联子对象与其父对象所必需的。

如果您想覆盖此行为,可以使用(尚未记录的)no_forced_sort布尔参数。

my $user_questions = 
    RoseDB::UserSecurityQuestion::Manager->get_user_security_questions(
    ... 
    sort_by  => 'RAND()', 
    no_forced_sort => 1); 

极有可能,这将导致与不正确的父对象被关联的子对象。你需要做的工作是确定性地基于t1的独特特征,但是在其他方面是随机的。也就是说,somefunc(t1.id)将是随机的,但对于给定的t1.id值,将始终返回相同的结果,从而使所有孩子都拥有正确的父母。

一个明显的(也许很多更加务实的)方法是获取用户$username所有的安全问题,然后就随机挑选二:

my $user_questions = 
    RoseDB::UserSecurityQuestion::Manager->get_user_security_questions(
    query  => [ 'user.username' => $username ], 
    with_objects => ['User','SecurityQuestion']); 

use constant NUM_RANDOM_QUESTIONS => 2; 

my @questions; 

for(1 .. NUM_RANDOM_QUESTIONS) 
{ 
    last unless(@$user_questions); 
    push(@questions, splice(@$user_questions, int(rand(@$user_questions)), 1)); 
} 

现在,你有你的(最大)NUM_RANDOM_QUESTIONS随机在@questions选定的问题。

+0

谢谢约翰。我越深入到你的工作中,我越感激它。由于最多有5个问题,我认为这种方法在这种情况下是可以接受的。也许有一天我会完全获得模块中的所有东西(尽管如此,:) – cliveholloway 2009-07-29 17:45:06

相关问题