Query base table and only return results met in n_n_relational table
- Single Page
Posted 15 June 2012 - 03:24 AM
I have a table that stores files and the files are catagorized using a relation_n_n.
The base table is named 'files' where all of the files are stored.
The selection table is name 'category' and has the different categories that files are identified with.
The relation table is name 'file_category' where file_id, category_id, and priority are all stored.
I am trying to create and display a view of a table that shows all of the files that are in a certain category. For example I have 1000 files, 200 of them are marked as 'short stories' I would like to create a CRUD table that displays only the files that are 'short stories', but I am having trouble because my $crud_like looks like this:
$crud->like('category','short stories');
So, of course I get 'unknown column' because the column 'category' only exist in the selection table which is not part of my base table 'files'.
I have been able to get the category column to show up in my files list table by using:
$crud->set_relation_n_n('category', 'file_category', 'category', 'file_id', 'category_id', 'name', 'priority');
Unfortionatly I still can't use $crud->like('category','short stories');
I created a model and tried writing a query to get the data... this query does what I want, but I can't figure out how to implement it in a CRUD list table.
$query = $this->db->query("SELECT * FROM files INNER JOIN file_category ON files.file_id=file_category.file_id WHERE category_id = (SELECT category_id FROM category WHERE name = 'short stories') ORDER BY files.file_id DESC") or die(mysql_error());
So, I'm stuck, can anyone tell me if it is possible to show results from a base table that meet a criteria that is in a selection table?
Posted 15 June 2012 - 06:15 AM
Is it really necessary for you to use n to n relation? Why do you not try grocery_CRUD 1 to n relation in which you can use where clause for the 4-th parameter? Sorry, if I asked a stupid question Sometimes it's difficult to understand at once all details.
Posted 15 June 2012 - 07:29 AM
I think you are correct, it could be a 1_n relationship. I tried to rewrite my function to do this:
$crud->set_table('files');
$crud->set_relation('file_id','file_category','category_id',array('category_id' => '42'),'priority ASC');
file_id is my primary key in my base table
file_category is my relation table
category_id is my related title field
42 is the primary key for 'short story' in the selection table
This didn't work so then I thought I would try to set $crud->set_table('file_category') that is my relationship table. I tried this
$crud->set_table('file_category');
$crud->set_relation('file_id','files', '{file_id} - {file_title} - {file_path}',array('category_id' => '42'),'priority ASC');
I can't get that to work either But, I'm pretty tired and don't think so well this late at night. I am going to get some sleep and give it another try tomorrow. Thanks for your direction.
Posted 15 June 2012 - 12:04 PM
public function files()
{
$crud = new grocery_CRUD();
$crud->set_table('files');
$crud->set_subject('Files');
$cat = $this->db->get_where('categories', array('category_id' => '1'))->row();
$crud->like('file_category', $cat->category_id);
// or if you want to use where clause
// $crud->where('file_category', $cat->category_id);
// if you want that user CAN change the category of files
$crud->set_relation('file_category', 'categories', 'category_name');
// if you want that user CAN NOT change the category of files
// $crud->set_relation('file_category', 'categories', 'category_name', array('category_id' => $cat->category_id));
// if you want to hide the category at all,
// so user CAN NOT see it on add/edit operations & CAN NOT change it
// $crud->set_relation('file_category', 'categories', 'category_name');
// $crud->change_field_type('file_category', 'hidden', $cat->category_id);
$output = $crud->render();
$this->_example_output($output);
}
Posted 15 June 2012 - 12:43 PM
$crud->set_table('file_category');
$crud->set_relation('file_id','files', '{file_title}');
$crud->like('category_id','21');
My next problem, which I think is connected to the way I did the above is that I want to do 'add_action' and give the user a hyperlink in the list table to download the files.
$crud->add_action('Download', '../img/icons/16x16/download_img_blue.png', '','ui-icon-image',array($this,'download_file'));
function download_file($primary_key , $row)
{
return site_url('/uploads/files')."/". {file_path};
}
I know that "return site_url('/uploads/files')."/". {file_path};" is wrong and that {file_path} is not available in the function, but I need file_path from the files table and I am not sure how to get it in that function.
Any direction appreciated... thanks.
Posted 15 June 2012 - 13:14 PM
function download_file($primary_key, $row)
{
return site_url('uploads/files/' . $row->file_name . '.pdf');
}
Posted 16 June 2012 - 13:58 PM
//$single_category_id is set by using a model to query the category table so if the user request the "short stories" page I first use a model to get the category_id from the category table. In this case "short stories" = '21'
$crud->set_table('files');
$crud->set_relation('file_id','file_category', 'file_id',array('category_id' => $single_category_id),'priority ASC');
$crud->like('category_id', $single_category_id);
As I mentioned above, I'm new and this probably isn't best practice, but it works. Thanks for your help.
Posted 16 June 2012 - 14:59 PM
Posted 16 June 2012 - 15:37 PM
[img]http://www.bytheowl.com/georgia/files_question.jpg[/img]
Posted 16 June 2012 - 17:36 PM
Posted 16 June 2012 - 17:39 PM
Posted 16 June 2012 - 17:53 PM
P.S. Why the search button doesn't work well with 1 to n relation? What errors have you got?
Posted 16 June 2012 - 18:46 PM
I have a function below named 'function manage_files' that allows site administrators to upload files, when they click the 'add' or 'edit' buttons they have the option to put the files in one category, or they can put the file in multiple categories. I also wanted to allow the site administrators to add another category if they needed to, so if they needed a new category they could go to a different grocery CRUD table to add a row to the "category" table then that category would be available to them when they went back to add a file. That sounds very confusing, but in the end I wanted to give the site administrators a way to add categories dynamically. I think now that this might be too much trouble and I should just hard-code it as you mentioned above.
function manage_files()
{
$data['title'] = 'Manage Files';
$crud = new grocery_CRUD();
$crud->set_subject('Files');
$crud->set_table('files');
$crud->columns('file_id', 'file_path', 'file_title', 'keywords', 'show_to', 'status', 'category');
$crud->set_relation_n_n('category', 'file_category', 'category', 'file_id', 'category_id', 'name', 'priority');
$crud->set_field_upload('file_path','..uploads/files/');
$output = $crud->render();
$this->_example_output($output);
}
This is what my Add Files looks like:
[img]http://www.bytheowl.com/georgia/add_files.jpg[/img]
I haven't created an organization for the files yet, they all go in one folder named '../uploads/files/ '. I hoped I could sort the files with grocery CRUD and just pull out the ones I wanted to share.
The ability to add files is only for site administrators, and that part seems to work well... at least the adding files works well, it is sorting the files when I want to get them back out that confuses me. So, the table that I am working on now (the last one in the picture above) is a table for users to be able to go to a page and view all the files in a certain category and then have the option to download a file. Because of your questions I suspect that I have added the files in a bad design and that I should start over on how I add the files and put them in categories. I would be much easier if the relation was 1_n
Your PS question about the search button not working:
The search button on 1_n relation will not work because I was sorting the results before I passed them to grocery CRUD to work with. I used:
//here I used the $user_submitted_category variable I get from the user to go into the category table and figure out which category_id they want.
$results1 = $this->get_data_model->getCategoryNumber($user_submitted_category);
foreach($results1 as $row){
$single_category_id = $row->category_id ;
}
//now that I have the $single_category_id that the user is looking for I queried the file_category table to get the file_id for all of the files that match up with the $single_category_id
$results2 = $this->get_data_model->getCDEListOfFiles($single_category_id);
$crud->where('status','active');
foreach($results2 as $row){
$crud->or_where('file_id', $row->file_id);
}
$crud->set_table('files');
So, as you can see I was able to get the function to loop through "or_where" statements to pull out the correct files... it worked well, but because these queries run every time the page is loaded it makes the search feature return all results every time. I do not get an error message from the search feature, it just keeps giving the same list.
I'm sure using a for each loop to construct a grocery CRUD function is not a best practice, I was just trying to figure out a way to make it work.
Sorry I am not great at explaining this situation, it is difficult to explain.
Posted 16 June 2012 - 23:18 PM