开发者

Trying to make a filter to retrieve data from related models

I have a Post model which hasMany PostField

every post can have several fields stored in the post_fields table..

post_fields has this structure: (id, post_id, name, value)

posts table has some common fields for all posts, but any additional fields should be stored in post_fields table..

I created a search form that is used to filter the posts

when specifying filters for the fields in the posts table, it works fine..

but I want to make the filter to work even on the other fields found in post_fields ..

I can retrieve the posts first then filter them manually, but i want something more efficient !

EXAMPLE: let's suppose that posts are describing some products..

post (id, title, created, price)
post_fields (id, post_id, name, value)

in this case, all posts have title, created and price开发者_JS百科..

but if a post (id=3) wants to have a weight field, we should do that by creating a record in post_fields, the record should be :

{ id: .. , post_id: 3, name: weight, value: .. }

it's easy now to filter posts according to price (e.g. price between min & max)..

but, what if i want to filter posts according to weight ??

e.g. i want all posts that have weight greater than 10 !!

I would like to achieve this preferably in one query, using joins maybe or subqueries ..

I don't know how to do that in cakePHP, so if any one has an idea, plz HELP !!

even if someone just has an idea but doesn't have details, that could help ...

thanx in advance !


There is no way to search against the children of a hasMany relationship. You will need to run your query against the PostFields model. ie: $this->PostField->find('all', array('conditions'=>array('PostField.name' => 'weight', 'PostField.value' > 10)));

If you want to do a query against both the PostField and Post models at the same time (ie: price < $1.00 and weight > 10, you will need to do a custom query, as CakePHP has no built-in solution for doing so TMK. Should look something like this:

$query = "SELECT ... FROM posts as Post, post_fields as PostField WHERE PostField.name = 'weight' AND PostField.value > 10 AND POST.price < 1.0 AND PostField.post_id = Post.id;"
$posts = $this->Post->query($query);

EDIT: I would do this. You're not going to get away with doing a single call, but this is still a clean solution.

$postIds = null;
if(/*we need to run query against PostFields*/) {
    $conditions = array(
        'OR' => array(
            array(
                'AND' => array(
                    'PostField.name' => 'weight',
                    'PostField.value' > 10
                )
            ),
            array(
                'AND' => array(
                    'PostField.name' => 'height',
                    'PostField.value' < 10
                )
            )
        )
    );
    $fields = array('PostField.id', 'PostField.post_id');
    $postIds = $this->Post->PostField->find('list', array('conditions'=>$conditions, 'fields'=>$fields));
}
$conditions = array('Post.price' < 1.0);
if($postIds) {
    $conditions['Post.id'] = $postIds;
}
$posts = $this->Post->find('all', array('conditions'=>$conditions));


You should look into using the Containable behavior for your models. This way, you can filter the returned columns as you like. (I think this is the type of filtering you want to do)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜