Anders
Anders

Reputation: 12746

"Undefined index" trying to add ORM object in Kohana php framework

I'm trying to add an ORM object to another one (one to many relationship) in Kohana:

$item = $cart->cartitems->where('productid', '=', $product->id);

    //if($item == null)//This apparently doesn't work in Kohana, it returns an object, even if not loaded, using the following:
    if (!$item->loaded()) {
        $item = new Model_Cartitem();
        $item->productid = $product->id;
        $item->quantity = 1; //TODO: Change to incrementation
        $item->totalprice = $product->price; //TODO: Change to incrementation
        $item->unitprice = $product->price;
        $item->productid = $product->id;
        $item->productnumber = $product->productnumber;
        $cart->add('cartitem', $item);
    }


    $cart->save();

Here's the cart class:

class Model_Cart extends ORM
{
    protected $_has_many = array('cartitems' => array());
}

and the cartitem class:

class Model_Cartitem extends ORM {
    protected $_belongs_to = array('cart' => array('foreign_key' => 'cartid'));
}

But when I run it I get the error "ErrorException [ 8 ]: Undefined index: cartitem ~ MODPATH\orm\classes\kohana\orm.php [ 1403 ]"

What does this "undefined index" refer to, and how do I fix this?

EDIT:

Changed the belongs_to in Model_Cartitem. Here is the definition of my foreign key in table cartitems (from NaviCat):

Foreign key in cartitems table

EDIT 2:

Here's the sql code for the tables:

cartitems:

CREATE TABLE `cartitems` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `productid` INT(11) NOT NULL,
    `quantity` INT(11) NOT NULL,
    `totalprice` DOUBLE NOT NULL,
    `cart_id` INT(11) NOT NULL,
    `productname` TEXT NOT NULL,
    `unitprice` DOUBLE NOT NULL,
    `productnumber` TEXT NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `cart_id` (`cart_id`),
    CONSTRAINT `cart_id` FOREIGN KEY (`cart_id`) REFERENCES `carts` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=2

carts:

CREATE TABLE `carts` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `username` TEXT NOT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=2

And since I changed the foreign key id name to cart_id I would think I should be able to use the simpler relationship definitions in the Model classes, so I changed to this:

class Model_Cart extends ORM
{
    protected $_has_many = array('cartitems' => array());
}

and

class Model_Cartitem extends ORM
{
    protected $_belongs_to = array('cart' => array());
}

Still doesn't work, still getting the undefined index: cartitem error...

EDIT 3:

Ok, so I tried doing the exact same thing in Asp.Net MVC 3, using the Entity Framework as ORM, just to see if there was something wrong with the database table definitions. But everything worked just fine there.

So at least I know now it has nothing to do with the database being faulty. So the problem must lie in the Kohana ORM and I must be doing something wrong there. I tried the suggestions from Yoda, but nothing has helped so far. This is getting frustratingly difficult, maybe I should look at CodeIgniter instead, which is supposed to be simpler... But I've kind of liked Kohana in other ways. Is there really no one who knows what the problem with my ORM classes is?

BTW: Is this part wrong? $cart->add('cartitem', $item); It's the only way I've found to add a relationship object, but at the same time, it says in the docs that you can add relationships in a many-to-many relationship this way... But if it doesn't apply to one-to-many, then how would I add the new cartitem to the cart?

Upvotes: 0

Views: 1297

Answers (1)

Anders
Anders

Reputation: 12746

Ok, so maybe I figured it out... If I'm right, it had nothing to do with my database being wrong, or the Model class relationships being wrongly defined. Rather, it seems to me that you couldn't actually use the add() method on a one-to-many relationship. It seems that to add a related object to a collection of a parent object you simply save the object, and manually add the foreign key id (cart_id) to relate them. If so, this is the difference from Asp.Net MVC and Entity Framework that I had a hard time grasping, because there you don't care about the foreign key, it is added automatically when you add an object to the child collection, like this in Asp.Net MVC: cart.cartitems.Add(item);

Oh, and also, when looping through the child collection, it seems you can't just do this:

foreach ($cart->cartitems as $item)

As I would have expected... But when I add a find_all() it works:

foreach ($cart->cartitems->find_all() as $item)

If this is not the correct answer, and there is in fact a way to add a child object with a special method, and the foreign key id is taken care of automatically, I would love to hear it, because that would make me more comfortable, but if not I hope this helps someone else trying to transition from Asp.Net MVC...

Upvotes: 1

Related Questions