TIP: Use Markdown or, <pre> for multi line code blocks / <code> for inline code.
These forums are read-only and for archival purposes only!
Please join our new forums at discourse.kohanaframework.org
Kohana 3 ORM save() for update a many-to-many
  • 1. I have a many-to-many relationship, but usually my pivot table have additional 'options', besides the two ids from tables. For example, my messages_users is:
    user_id | message_id | is_group (bool) | unread (bool)
    is there any way I can update, without using SQL or non-ORM way, either the 'is_group' or the 'unread' columns?

    2. Also, if my user has_many messages, is there any way I can do like ORM::factory('user', $id)->messages->values($values)->save()?

    3. Another question, how should I name pivot tables models and filenames? Model_Messages_User and messages_user.php? Model_Message_User and message_user.php?
  • this is really frustrating, i'm stuck in the same issue for days now
  • why this:

    $msg =
    ORM::factory('message_user', array(
    'message_id' => $this->p('id'),
    'user_id' => $_SESSION['user_id']
    ));

    $msg->unread = 0;
    $msg->save();

    generates this?

    UPDATE `messages_users` SET `unread` = 0 WHERE `message_id` = '1'


    makes no sense at all.
    model:

    class Model_Message_User extends adminorm {
    protected $_primary_key = 'message_id';
    protected $_updated_column = null;
    protected $_created_column = null;
    protected $_table_name = 'messages_users';
    protected $_belongs_to = array('message' => array(), 'user' => array(), 'role' => array());
    }
  • this seem to be a bug, in the Kohana/orm.php file

    /**
    * Finds and loads a single database row into the object.
    *
    * @chainable
    * @param mixed primary key
    * @return ORM
    */
    public function find($id = NULL)
    {
    if ( ! empty($this->_load_with))
    {
    foreach ($this->_load_with as $alias)
    {
    // Bind relationship
    $this->with($alias);
    }
    }

    $this->_build(Database::SELECT);

    if ($id !== NULL)
    {
    // Search for a specific column
    $this->_db_builder->where($this->_table_name.'.'.$this->_primary_key, '=', $id);
    }

    return $this->_load_result(FALSE);
    }


    the $id isn't checked for an array! so the correct code would be:

    if ($id !== NULL)
    {
    if (is_array($id)){
    foreach ($id as $column => $value){
    $this->_db_builder->where($this->_table_name.'.'.$column, '=', $value);
    }
    } else {
    // Search for a specific column
    $this->_db_builder->where($this->_table_name.'.'.$this->_primary_key, '=', $id);
    }
    }


    also inside the save() method (still in orm):

    $query = DB::update($this->_table_name)
    ->set($data)
    ->where($this->_primary_key, '=', $this->pk()) // Updating just one key?! No idea how to proceed here
    ->execute($this->_db);
  • ORM loads one-to one relationships, but not many-many relationships. Use $msg->add() to add for relationship objects.
  • nope, won't do, it's creating an insert instead of an update, I just want to update
    ORM::factory('message', $this->p('id'))->add('users', ORM::factory('user', $_SESSION['user_id']), array('unread' => 0))->save();
    nor
    ORM::factory('user', $_SESSION['user_id'])->add('messages', ORM::factory('message', $this->p('id')), array('unread' => 0))->save();
    I submitted a patch, but "they" said it was invalid
  • Hi, I'm stuck with the same problem to update a many-many relationship table via ORM that has additional columns. The ORM always results an INSERT query if there is no id given, and an array as compound key is not an option, I think this feature should be added, right ?

  • Compound keys are probably not getting added any time soon (if ever). If you need to select the pivot table, then make a model for it, create a one to many relationship on both sides, and add an auto incrementing id to the middle table. If that's too much work for you, then simply create custom methods in your models and use the query builder manually.

    Edit: If your pivot table has data other than the pivot data, then stop thinking of it as a pivot table. It's just a normal table with 2 one-to-many relationships going to other tables.

  • @Zeelot3k exactly what you are saying! I don't understand the trouble here? Extra data in a pivot table isn't a pivot table.. create a new model instead :)

    • menus
      • id
      • title
    • menus_pages
      • id_menu
      • id_page
      • level
    • pages
      • id
      • title

    So your modelling is:

    • menu
    • page
    • menu_page

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion