如何在ORM中制作过滤器?

时间:2013-02-11 17:40:32

标签: php kohana kohana-orm

例如我的Model有方法get_objects,我按照以下来源搜索它们:

class Model_Object extends ORM {

public function get_objects($filters = array())
{

        if (!empty($filters['Role']))
            $role = $filters['Role'];
          else
        $role = NULL;


        $objects = ORM::factory('object')
                         ->where('RoleId','=',$role)
                         ->find_all();

       return $objects;
}

所以代码只有在过滤器存在时才会起作用,当过滤器中没有值时我将没有任何记录而不是所有记录(我想要所有记录),如何使其更好?

1 个答案:

答案 0 :(得分:1)

听起来你想让ORM在哪里调用依赖于相关的过滤键存在。以下代码应该做你正在寻找的东西,它对我有用,它能做你想做的吗?

如果它不允许键名/字段名称区分(RoleRoleId),那将更加简洁。

application/classes/Model/Object

class Model_Object extends ORM {

    // Map from filter key names to model field names
    protected static $_filter_map = array(
        'Role' => 'RoleId',
        // ...
    );

    public static function get_objects($filters = array())
    {

        $objects = ORM::factory('object');

        foreach($filters as $key => $value)
        {
            if ($field = Arr::get(self::$_filter_map, $key))
            {
                $operator = (is_array($value)) ? 'IN' : '=';
                $objects->where($field, $operator, $value);
            } else {
                throw new Kohana_Exception(
                    'Unknown filter key :key',
                    array(':key' => $key)
                );
            }
        }

        return $objects->find_all();
    }
}

一些例子,首先是所有对象:

Model_Object::get_objects( array() );

RoleId等于2的所有对象:

Model_Object::get_objects( array('Role' => 2) );

在(2,3,5)AND user_id = 1中具有role_id的所有对象:

Model_Object::get_objects( array(
    'Role' => array(2,3,5),
    'User' => 1
) );

请注意,最后一个要求您拥有:

protected static $_filter_map = array(
    'Role' => 'role_id',
    'User' => 'user_id', // where `user_id` is a db field name
    // ...
);

或者将get_objects函数更改/简化为

$objects = ORM::factory('object');

foreach($filters as $key => $value)
{
    $field = Arr::get(self::$_filter_map, $key, $key);
    $operator = is_array($value) ? 'IN' : '=';
    $objects->where($field, $operator, $value);
}

return $objects->find_all();