nullpointerexception
nullpointerexception

Reputation: 41

Update a row using idiorm and php

I have this function to update a record, but i cannot it fails and send me a "Primary key ID missing from row or is null" message, how can I fix it?

public static function update_child($data)
{
    try
    {
        $update= ORM::for_table("dm_child",DM_TAG)
                        ->where_equal($data["id_child"]);

        $update -> set(array(
            "gender" => $data["gender"]
            "age_year" =>$data["year"]
            "age_month" => $data["month"]

        ));
        $update -> save();
    }
    catch(PDOException $ex)
    {
        ORM::get_db()->rollBack();
        throw $ex;
    }
}

Upvotes: 3

Views: 6173

Answers (7)

Ghanshyam Nakiya
Ghanshyam Nakiya

Reputation: 1712

if in table primary key/ field name not id then following id column overrides required default id (primary_key) to replace with other id name (primary_key)

    ORM::configure('id_column_overrides', array(
        'user'  => 'user_id',
    ));

    $update = ORM::for_table('user')->find_one(1);
    $update->name = "dev";
    try{
        $update->save();
    }catch(Exception $e){
        echo $e;
    }

    print_r($update);

Upvotes: 0

OneBitAhead
OneBitAhead

Reputation: 81

This also happens when the id field name is ambiguous, e.g. when joining two tables both having an id column. This is the case with referenced tables

Model::factory('tableOne')
->left_outer_join('tableTwo', array('tableOne.tableTwo_id', '=', 'tableTwo.id'))
->find_one($id);

In these cases set an alias to the ID column of the parent tableOne to later access it while saving. Make sure that you also select other columns you need - e.g. by ->select('*'):

Model::factory('tableOne')
->select('*')
->select('tableOne.id', 'id')
->left_outer_join('tableTwo', array('tableOne.tableTwo_id', '=', 'tableTwo.id'))
->find_one($id);

Upvotes: 0

cmeza
cmeza

Reputation: 369

The answer is indeed the one provided by @iNpwd for changing the default 'id' column name for queries on a per table basis:

ORM::configure('id_column_overrides', array(
    'table_name'  => 'column_name_used_as_id',
    'other_table' => array('pk_1', 'pk_2') // a compound primary key
));

The thing that was biting me on getting it to recognize my query was WHERE I was changing the ORM::configure values. I was not in the correct file.

A deeper link to specifically the ID Column configuration: http://idiorm.readthedocs.org/en/latest/configuration.html#id-column

Upvotes: 2

shmup
shmup

Reputation: 944

I'm sure I'll learn the reason behind this, but let me tell you all I understand at the moment, and how I "fixed" it.

Here is the beginning of idiorm's save function:

public function save() {
    $query = array();
    // remove any expression fields as they are already baked into the query
    $values = array_values(array_diff_key($this->_dirty_fields, $this->_expr_fields));
    if (!$this->_is_new) { // UPDATE
        // If there are no dirty values, do nothing
        if (empty($values) && empty($this->_expr_fields)) {
            return true;
        }
        $query = $this->_build_update();
        $id = $this->id(true);

Right there, on that last line, when trying to access the $this->id, you are getting an exception thrown:

throw new Exception('Primary key ID missing from row or is null');

$this does not contain an id property. I'm not really sure how it could. The example given both on their homepage and in the docs doesn't do anything special to address this. In fact I am copying them 1:1 and still yielding the same error as you.

So, all that said, I fixed this error by just adding in my own id:

$crop = ORM::for_table('SCS_Crop')->find_one($id);
$crop->id = $id;
$crop->Name = "Foo";
$crop->save();

Upvotes: 0

charles
charles

Reputation: 438

I just met this problem 2 minutes ago. The real reason is, you forgot select id field in querying. demo:

$demo = ORM::for_table('demo')->select('field_test')->find_one($id);
$demo->field_test = 'do';
$demo->save();

You will get the error. change to :

$demo = ORM::for_table('demo')->select('field_test')->select('id')->find_one($id);

It will fix the problem.

Some tips in documents: https://github.com/j4mie/idiorm/blob/master/test/ORMTest.php

/** * These next two tests are needed because if you have select()ed some fields, * but not the primary key, then the primary key is not available for the * update/delete query - see issue #203. * We need to change the primary key here to something other than id * becuase MockPDOStatement->fetch() always returns an id. */

Upvotes: 1

iNpwd
iNpwd

Reputation: 91

Idiorm assumes that the name of the primary key is 'id', which is not that, in your case. Therefore you have to explicitly specify it to Idiorm:

<?php
    ORM::configure('id_column_overrides', array(
    'dm_child' => 'id_child',
    'other_table' => 'id_table',
));

See Docs>Configuration.

Upvotes: 4

Richard
Richard

Reputation: 536

I've never used idiorm, so cannot guarantee that my answer will work for you, but from this page and under "Updating records", we have an example which is similar but slightly different to yours.

// The 5 means the value of 5 in the primary-key column
$person = ORM::for_table('person')->find_one(5);

// The following two forms are equivalent
$person->set('name', 'Bob Smith');
$person->age = 20;

// This is equivalent to the above two assignments
$person->set(array(
    'name' => 'Bob Smith',
    'age'  => 20
));

// Syncronise the object with the database
$person->save();

Upvotes: 0

Related Questions