Trying to make a filter to retrieve data from related models
I have a Post
model which hasMany
PostField
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..
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百科
..
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
)..
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)
精彩评论