many-to-many relationship in CI (not using ORM)
I'm implementing a categories system in my CI app and trying to work out the best way of working with many to many relationships.
I'm not using an ORM at this stage, but could use say Doctrine if necessary.
Each entry may have multiple categories.
I have three tables (simplified)
Entries: entryID, entryName
Categories: categoryID, categoryname
Entry_Category: entryID, categoryID
my CI code returns a record set like this:
entryID, entryName, categoryID, categoryName
but, as expected with Many-to-Many relationships, each "entry" is repeated for each "category".
What would the best way to "group" the categories so that when I output the results, I am left with something like:
Entry Name
Appears in Category: Foo, Bar
rather than:
Entry Name
Appears in Category: Foo
Entry Name
Ap开发者_高级运维pears in Category: Bar
I believe the option is to track if the post ID matches a previous entry, and if so, store the respective category, and output it as one, rather than several, but am unsure of how to do this in CI.
thanks for any pointers (I appreciate this is may be a vague/complex question without a better knowledge of the system).
i created a helper for this
function has_many( $results, $child_table, $parent_key, $child_key ){
if( count( $results ) == 0 ){
return $results;
}
$CI = &get_instance();
$ids = array();
$result_len = count( $results );
for ($i=0; $i < $result_len; $i++) {
array_push( $ids, $results[ $i ][ $parent_key ] );
$results[ $i ][ $child_table ] = array();
}
$q = $CI->db->where_in( $child_key, $ids )->get( $child_table );
$children = $q->result_array();
foreach( $children as $child ):
for ($i=0; $i < $result_len; $i++) {
if( $results[ $i ][ $parent_key ] == $child[ $child_key ] ){
array_push( $results[ $i ][ $child_table ], $child );
}
}
endforeach;
return $results;
}
use example
$q = $this->db->get( 'parent_table' );
$nested_result = has_many( $q->result_array(), 'child_table', 'id', 'parent_table_id' );
print_r( $nested_result );
and if you needed extra query params on the children, add them as usual
$q = $this->db->get( 'parent_table' );
$this->db->order_by( 'some_field', 'ASC' );
$nested_result = has_many( $q->result_array(), 'child_table', 'id', 'parent_table_id' );
print_r( $nested_result );
Push the category select off to a second select. For each entry record, feed the entryID into this select
select c.categoryID, c.categoryname
from category c
join entry_category ec on ec.categoryID = c.categoryID
where ec.entryID = ?
Also, if this categorization scheme you're developing is equivalent to what is referred to as tagging or folksonomy on blogs and other social sites, you should consider using a third party package such as freetag
精彩评论