1

I'm trying to insert a row with the table->save() method, but the method executes an UPDATE instead. There is no row available, so it needs to be inserted. Does anyone know how to get it inserted?

My code:

$tableLocation = $this->getTable("Location", 'Table', array());
if (!$tableLocation->save($data))
{
    $this->setError($user->getError());
    return false;
}

This runs the query UPDATE, but it needs to be INSERT if not available.

EDIT: Ok so I found the solution, partly. My construct method in my Table class:

parent::__construct('#__matches_location', 'user_id', $db);

Because I set the primary key to the user_id field it tried to update. So I changed it to this:

parent::__construct('#__matches_location', 'id', $db);

But now I get another issue:

Duplicate entry '185' for key 'user_id'

This is correct, there is a record for 185 in it already.

The correct way is to use the id as primary key, but then I need to change the Location table store (?) method to set everything right. Is that correct?

Ok so I tried the following:

public function bind($array, $ignore = '')
    {

        if($this->load(['user_id' => $array['user_id']])) {
            $array['id'] = $this->id;
        }

        //echo $this->id;

        return parent::bind($array, $ignore);
    }

This gives me an memory error. Probably a memory leak somewhere. So I moved the code to the store fucntion:

public function store($updateNulls = false)
    {

        if($this->load(['user_id' => $this->user_id])) {
            $this->id = $this->id;
        }

        return parent::store($updateNulls);
    } 

But this doesn't do anything, because well, I load the row, and thus the new values sent are being overwritten. Do I need to get these values first and then change them in the new loaded row?

It all seems so cumbersome, there must be an easier way right? I cannot imagine this is some sort of unique situation.

SOLUTION:

//Store data, check if records exist 
if($tableLocation->load(['user_id' => $data['user_id']])) { $data['id'] = $tableLocation->id; } 

if (!$tableLocation->save($data)) 
{ 
     $this->setError($user->getError()); 
     return false; 

}

3
  • According to docs.joomla.org/Using_the_JTable_class, you don't need to bother passing in 'Table' or array() -- these are default parameters. This advice will not resolve your question, but it does mean that you can simplify your call to $this->getTable("Location"). Your question is missing some vital details. What does $data contain? You say that a row is being updated -- is only one row updated or multiple? How are the updated rows targeted? What is the rendered executed query? May 20, 2021 at 22:04
  • See my updated question
    – Kuubs
    May 21, 2021 at 10:45
  • Please never add a "solution" section to a question. If you have a unique way to resolve the page, please add a new answer and remove the solution from the question. Mar 9, 2022 at 22:44

1 Answer 1

2

save() calls store().

Store() works like this: If a primary key value is set the row with that primary key value will be updated with the instance property values. If no primary key value is set a new row will be inserted into the database with the properties from the Table instance.

Please check, if the primary key of the database table is set in your $data objekt.

2
  • Yes, the primary key (see my above answer) was set. I changed it to the initial primary key "id". Now I get another error (duplicate key user_id) which is also correct because I made user_id unique. I probably have to change the store() or check() method to check if the user_id is already available, and if so get the primary key and add that to the database?
    – Kuubs
    May 21, 2021 at 10:50
  • Found the solution, moved it into my model, instead of trying to make it work in my Table class: //Store data, check if records exist if($tableLocation->load(['user_id' => $data['user_id']])) { $data['id'] = $tableLocation->id; } if (!$tableLocation->save($data)) { $this->setError($user->getError()); return false; }
    – Kuubs
    May 21, 2021 at 11:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.