Problem with multi selector and data saving

edited January 2013 in Bug Reports
Hi all!
I'm new to Fuel CMS and I'm trying to develop a custom module (a catalogue); all is workin' well except for a problem I'm having this days. This is the database portion interested:

catalogue_attributes: id | nome | tipo
catalogue_sets: id | titolo
catalogue_attributes_to_sets: attribute_id | set_id

Just to explain some field from italian to english:
nome => name, tipo => type, titolo => title

Right. Now, in the Sets creating/editing form, Fuel autocreate the input for the title; using the form_fields() method, I'd like to add the multiselector (like the post-to-category multi in the blog module) to add some attribute to the set (a set is a combination of many attributes). To do this, this is the code I use:

function form_fields($values = array()) { $fields = parent::form_fields(); $CI =& get_instance(); $CI->load->module_model(CATALOGUE_FOLDER, 'catalogue_attributes_model'); $CI->load->module_model(CATALOGUE_FOLDER, 'catalogue_attributes_to_sets_model'); /* ATTRIBUTES MULTI */ $attribute_options = $CI->catalogue_attributes_model->options_list(); $attribute_values = (!empty($values['id'])) ? array_keys($CI->catalogue_attributes_to_sets_model->find_all_array_assoc('attribute_id', array('set_id' => $values['id']))) : array(); $fields['attributes'] = array('label' => 'Attributes', 'type' => 'array', 'options' => $attribute_options, 'value' => $attribute_values, 'mode' => 'multi'); return $fields; }

In the catalogue_attributes_to_sets_model I have defined the _common_query like this:

function _common_query() { $this->db->select($this->_tables['catalogue_attributes_to_sets'].'.*, '. $this->_tables['catalogue_sets'].'.id AS set_id, '. $this->_tables['catalogue_sets'].'.titolo AS set_titolo, '. $this->_tables['catalogue_attributes'].'.id AS attr_id, '. $this->_tables['catalogue_attributes'].'.nome AS attr_nome, '. $this->_tables['catalogue_attributes'].'.tipo AS attr_tipo' , FALSE); $this->db->join($this->_tables['catalogue_attributes'], $this->_tables['catalogue_attributes_to_sets'].'.attribute_id = '.$this->_tables['catalogue_attributes'].'.id', 'left'); $this->db->join($this->_tables['catalogue_sets'], $this->_tables['catalogue_attributes_to_sets'].'.set_id = '.$this->_tables['catalogue_sets'].'.id', 'left'); }

Finally, in the on_after_save() hook (in the Sets module), I've inserted the following code:

function on_after_save($values) { $CI =& get_instance(); $CI->load->module_model(CATALOGUE_FOLDER, 'catalogue_attributes_to_sets_model'); $saved_data = $this->normalized_save_data; $set_id = $values['id']; $attributes = (!empty($saved_data['attributes'])) ? $saved_data['attributes'] : array(); $CI->catalogue_attributes_to_sets_model->delete(array('set_id' => $set_id)); foreach ($attributes as $attr) { $attribute_set = $CI->catalogue_attributes_to_sets_model->create(); $attribute_set->set_id = $set_id; $attribute_set->attribute_id = $attr; $attribute_set->save(); } }

The multiselector is a component I've used before (in the products form to associate the categories) and it works correctly; but in the Sets form, i receive an "OK" message on save only if I disable the multiselector (in other words saving only the set's title). If I enable the multiselector, the saving process doesn't work correctly and the after_save method doesn't run. To better describe the scenario, here is what it happens:

- multi disabled: all OK
- multi enabled but no item selected (right list empty): all OK but obviously no attribute connected with the set
- multi enabled and some attribute selected (right list not empty): saving not working and after_save not running

I can't figure it out.. the problem seems to be in the multiselector, but it seems to be builded well.. (no errors on screen, no errors if I don't select items). I've tried to do a little debug, logging the $_POST array that arrives to the save() method on MY_Model, and all is OK.
Any ideas? 1 day trying to fix this and no result :(

Thank you all!

Comments

  • edited 4:11AM
    Have you debugged the MY_Model save method to see if it gets to the on_after_save part within that method?

    As an FYI, the 1.0 beta provides a much more simplified way of creating model
    relationships without the need for extra models and tables by using a belongs_to and has_many syntax:
    https://github.com/daylightstudio/FUEL-CMS/tree/1.0
    https://github.com/daylightstudio/FUEL-CMS-User-Guide-Module
  • edited 4:11AM
    Thank you for the reply :) Now I've installed the 1.0beta version and using the new model relationships. I've had some problem with the $foreign_keys property:
    in my Products model, I've set
    public $foreign_keys = array('manufacturer_id' => array(CATALOGUE_FOLDER => 'catalogue_manufacturers_model'));
    and correctly the form shows a select with the list of manufacturers, with key = id and value = name.
    But if I do the same thing on the Images model (one-to-many relationship, a product has one or more images), the select is not formed well. I write:
    public $foreign_keys = array('product_id' => array(CATALOGUE_FOLDER => 'catalogue_products_model'));
    And the select has key = id and value = [some_unknown_id]. I've set the options_list() method on the products_model like this:
    function options_list($key = 'id', $val = 'nome', $where = array(), $order = 'nome') { $return = parent::options_list($key, $val, $where, $order); return $return; }
    but is not working.. $val is empty, so the default value is not applied. I've had to modify the method like this:
    function options_list($key = 'id', $val = 'nome', $where = array(), $order = 'nome') { if (empty($key)) $key = 'id'; if (empty($val)) $val = 'nome'; if (empty($order)) $order = 'nome'; $return = parent::options_list($key, $val, $where, $order); return $return; }
    to overwrite the values in case of emptiness. Strange, uh? Is this some sort of bug?

    ----------------------------------------------------

    Just a little advisory on the blog module:
    the tree() method doesn't work (loading loop on screen) because of wrong model loading. The code
    $CI->load->module_model(FUEL_FOLDER, 'relationships_model');
    should be
    $CI->load->module_model(FUEL_FOLDER, 'fuel_relationships_model');
    according to the name of the model in fuel/modules/fuel/models :-)
  • edited 4:11AM
    The options_list will generate the options list based on the first to fields of your table with the second being the label. What's the second field of your table? Also, you can debug the query by using $this->debug_query() after the parent::options_list(...) call.

    If an image can belong to many products, do you want to use a belongs_to property in your model instead which will give you a multi select to choose the products that belong to your image?

    Thanks for the heads up on the blog_posts_model tree method not working correctly.
Sign In or Register to comment.