Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Orm delete behavior
  • Hello everyone !
    I experienced a strange problem when I try to delete an entry (conversation here) with related model that I have to delete before (attachments). The controller lloks like this :

    public function post_delete()
    {
    // POST data
    $id = \Input::post('id');
    $control = \CiData\Model\DeliberateControl::find($id);
    if($control == null)
    {
    return $this->response('Control not found', 404);
    }

    // Delete all Conversation (messages, attachments)
    $conversation = $control->wf_msg_conversations;
    $attachments = $conversation->wf_msg_attachments;
    foreach ($attachments as $i => $attachment)
    {
    // Delete file from server
    \File::delete('modules/messages'.DS.$conversation->name.'_'.$conversation->id.DS.$attachment->name);

    $attachment->delete();
    }

    $conversation->delete();

    $control->delete();
    return $this->response('SUCCESS');
    }
    Everythng work perfectly for attachments but when I call $conversation->delete(), this error is raised :

    Fuel\Core\Database_Exception [ 23000 ]:
    SQLSTATE[23000]: Integrity
    constraint violation: 1048 Column 'conversation_id' cannot be null with
    query: "INSERT INTO `wf_msg_attachments` (`name`, `added_at`,
    `conversation_id`) VALUES ('ExPageAccueille.png', '2018-01-09', null)"

    I probably make something wrong... Someone already experienced this ?
  • HarroHarro
    Accepted Answer
    How are your relations defined?

    it should be: conversation has_many attachment, attachment belongs_to conversation.

    And yu don't have to delete the attachments manually, if you define the relation as cascade_delete true, the ORM will handle that for you.
  • Hello Harro,
    My relations are defined like this :

    Conversation Model :

    protected static $_has_many = array(
    'wf_msg_messages' => array(
    'model_to' => 'Messages\\Model\\Message',
    'key_from' => 'id',
    'key_to' => 'conversation_id'
    ),
    'wf_msg_attachments' => array(
    'model_to' => 'Messages\\Model\\Attachment',
    'key_from' => 'id',
    'key_to' => 'conversation_id'
    )
    );
    Attachment Model :

    protected static $_belongs_to = array(
    'wf_msg_conversations' => array(
    'model_to' => 'Messages\\Model\\Conversation',
    'key_from' => 'conversation_id',
    'key_to' => 'id'
    )
    );
    Ok I'm going to try to define cascade_delete to true and only delete files in foreach loop.
  • Put cascade_delete to true fixe issue !
    But I still wondering about error message ! Why INSERT INTO Sql request is called by delete method in my previous situation ?
  • No loop is needed, conversation->delete() should automatically delete all attachments when cascade_delete is set to true.

    No clue why it would want to insert an attachment record. 

    It might be related to the fact that the loaded Conversation object is not aware that you've deleted it's attachments. So when it is processing the delete request, it sees a number of attachment objects, and as cascade_delete is false it thinks you've indicated you don't want to delete the attachments. As they no longer exist, there are seen as new, and the ORM tries to save them. Which it can't, as the required parent record is already gone.
  • My attachments are references to files on server so I need to keep my loop to delete files on server unless I can do this in another way ?

    Ok I have a better understanding of Fuel Orm's relations now :) !
  • HarroHarro
    Accepted Answer
    Ok, clear. 

    But at least you don't need the $attachment->delete() there anymore, so you save on quite a few queries.

    You could add an observer to the attachment model, that acts on delete, and deletes the file before the record is deleted. Then it will happen automatically and transparently.
  • I will do this today !
    Big thanks Harro for your help :) !

Howdy, Stranger!

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

In this Discussion