根据年龄范围基于数据库表中的生日来搜索用户

时间:2013-03-04 10:02:51

标签: yii

现在,我有一个数据库表,以“datetime”格式存储有关用户及其birhtdate的信息。该数据库表与相应的ActiveRecord模型相关联。

在用户搜索表单中,我希望按年龄范围实现搜索(分别有两个表单下拉字段,“从”和“到”年龄)。

我认为我必须将通过表单提交的年龄转换为实际的“日期时间”日期,然后再对数据库表执行搜索。

我对CDb Criteria和Yii的理解还不够。这似乎是社交网络中的常见问题,但我无法找到足够的答案来回答我的问题。

我在等待回复的时候找到了一个解决方案。但我认为我可能没有直接思考所以我可能想出了一些不太合理的东西。但它确实有效。

我在用户模型中创建了两个变量:

        public $fromBirthdate;
        public $toBirthdate;

我将搜索表单中的搜索字段从单个生日日期字段更改为字段“to”和“from”,其中包含分别表示最小和最大年龄的整数。

我将这些字段绑定到模型中新创建的变量。

<div class="row">
        <?php echo $form->label($model,'fromBirthdate'); ?>
        <?php echo $form->textField($model,'fromBirthdate'); ?>
    </div>

    <div class="row">
        <?php echo $form->label($model,'toBirthdate'); ?>
        <?php echo $form->textField($model,'toBirthdate'); ?>
    </div>

&GT;

然后我写了一个函数,根据当前时间将年龄转换为生日:

//transforms age into birthdate based on current date
//@param integer age
//@param integer default age (what age should be applied in case the age parameter is null)
//$returns string date formatted MySQL timestamp

public function getBirthdate($age, $defaultAge)
{
    if($age == null)
    $age = $defaultAge;

    $birthDate = date('Y-m-d H:i:s',strtotime("-" . $age . "years", time()));
    return $birthDate;
}
  • 我通过添加以下行在模型的search()函数中摆弄了一些CDbCriteria实例:

 
//specifies range of age the users should be searched within
    //if either of the age fields ("to" or "from" age") was not filled, default age is applied
    //default age range is from 10 to 110 years old. 
    $criteria->addBetweenCondition('birthdate', $this->getBirthdate($this->toBirthdate, 110), $this->getBirthdate($this->fromBirthdate, 10));

总而言之,当用户通过搜索表单提交年龄范围时,它将作为整数存储在这两个变量中。然后,他们会被包含日期时间戳的字符串覆盖,这些时间戳是从提交的年龄转换而来的。

如果用户没有在搜索中指定最小和最大年龄,我必须在游戏中引入所谓的“默认最小和最大年龄值”。我不确定这个是最明智的想法,但它适用于我。

1 个答案:

答案 0 :(得分:0)

我建议使用参数化的命名范围:http://www.yiiframework.com/doc/guide/1.1/en/database.ar#named-scopes

将以下方法添加到您的模型中,确保将createtime更改为您自己的日期时间列的名称:

    public function byAge($to, $from)
    {
        $from = new DateTime("-$from years");
        $fromDate = $from->format('Y-m-d H:i:s');

        $to = new DateTime("-$to years");
        $toDate = $to->format('Y-m-d H:i:s');

        $this->getDbCriteria()->mergeWith(array(
            'condition' => 't.createtime BETWEEN :from AND :to',
            'params' => array(
                ':from' => $fromDate,
                ':to' => $toDate,
            ),
            'order' => 't.createtime DESC', // Youngest first
        ));

        return $this;
    }

从表单中获取$ to和$ from的值,其中$ to是较小的年龄,$ from是较大的年龄。然后使用该方法,通过执行以下操作来更改搜索方式:

$model = new User;
$to = 12;
$from = 25;
// Set other model attributes based on user input
$dataProvider = $model->byAge($to, $from)->search();

我用我自己的数据对此进行了测试,但它确实有效,但如果您无法与它合作,请告诉我。