Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
My model doesn't want save related
  • Hi.

    I have a many to many relation betwen two models perfectly working. But when i want to add a related object and save, the related is not saved. I have the cascade_save set to true on my model, and no errors. the save method return true, i can access the related in the page, but the relation is not written in table_through. When i refresh, relation doesn't exist...

    My code, expects validations details, ect, looks like the one in the doc :

    $user = Model_User::find(8);
    $user->posts[1] = Model_Post::find(1);
    $user->save(); // return true


    What's going wrong here ? Thanks.

    Edit : i forgot to say it's the same problem for delete, cascade_delete is set to true, but when i get my $object->related, unset the wanted key and save, it's return success, but the relation still exists...

  • Are you use your relations are defined ok?

    And which version of Fuel?
  • Version 1.5.

    My relations works fine and all parametres are correct in models...
  • Appearently not all relations...

    I don't know what the status of ORM was in 1.5, but given the fact that this is very basic functionality, I would find it odd if it turned out to be broken.

    Just ran a test here using 1.5, with a many-to-many relation, and that seems to work fine:
            // truncate persons, jobs and persons_jobs
            DBUtil::truncate_table('persons');
            DBUtil::truncate_table('jobs');
            DBUtil::truncate_table('jobs_people');

            // create test data
            $query = DB::insert('persons', array('name'))->values(array('Person 1'))->execute();
            $query = DB::insert('jobs', array('name'))->values(array('Job 1'))->execute();
            $query = DB::insert('jobs', array('name'))->values(array('job 2'))->execute();
            $query = DB::insert('jobs', array('name'))->values(array('job 3'))->execute();

            // relate person 1 to Job 2
            $person = Model_Person::find(1);
            $person->job[2] = Model_Job::find(2);
            $person->save();

    The save generates the insert in the join table without problems:
    INSERT INTO `jobs_people` (`person_id`, `job_id`) VALUES (1, '2')
  • Well i dont know... i try to find it out for hours, but cascades still not working with both objects existing. When i create a new object and add a relation it's work.
  • Have you enabled DB profiling? Do you see any queries being generated?
  • Yep, i got an UPGRADE request with only editing the table without the relation. I try with or withour cascade_save for both models, i did exactly what the doc say, i looked sample code and tutorials, There is absolutly no reason to not working and though, it doesn't work...

    <Edit> I forgot : When i create one of the two model object at the time to insert, it's work fine. It's just when the two models objects exists, then it fail. I really dont know why but it's start to be really ennoying to have that kind of problem on an operation supposed to be as simple as that.
  • Which is exactly like the test code I posted above, and which works fine here?

    Is this an existing application? Is upgrading to 1.6.1. an option (or at least test that bit of code in 1.6.1. to see if you still have it)?

    I'm still puzzled, and since I can't reproduce it, I don't know where to start...
  • One other thought: is the ORM package you use also v1.5? Or maybe older?
  • The ORM package is 1.5 too. 

    The relation in post model :



    protected static $_many_many = array(
            'tags' => array(
                'key_from' => 'id',
                'key_through_from' => 'post_id', 
                'key_through_to' => 'tag_id',
                'model_to' => 'Model_tag',
                'key_to' => 'id',
                'table_through' => 'posts_tags',
                'cascade_save' => false,
                'cascade_delete' => false
            )
    );


    The code :

    if(false !== ($post = Model_Post::query()->where('id', $id)->related('tags')->get_one())) {
                
        if(Input::post('tag') && false !== ($tag = Model_Tag::query()->where('id', Input::post('tag'))->get_one()))     {
            
            $post->tags[Input::post('tag')] = $tag;
            
            if($post->save()) Session::set_flash('success', 'success');
            
            else Session::set_flash('error', 'error');
            
         }
    }

    The save() return already true, even if it's not working. Funny thing, if I replace 

    $tag = Model_Tag::query()->where('id', Input::post('tag'))->get_one()

    By : 

    $tag = Model_Tag::forge(array('title'=>'myTag'))

    It create a new tag, and insert it in the relation table successfully. So the problem is my query to get the existant tag ? I dont think so, i var_dumped it, it's a Model_Tag object perfectly working.

  • I tried this exact code here (using my two test models), and the result is a success, the junction record is inserted on save without problems.

    How about the relation definition in Model_Tag? Is that there, and correct? Relations have to be defined symmetrical.

    And a side-note: why the test for false in your if's? afaik get_one() never returns false.
  • Yeah, old habit, you're right.

    The many many in Model_Tag is correct too, because as i said, if i create a tag in the code instead of getting one in database, my relation works.


  • Absolutely weird. I can not explain it. Your code works here.

    You're sure Input::post('tag') returns something useful? The last thing I can think of...
  • Yeah, isn't it ? And the Input::post('tag') is fine, if it wasn't, my var_dump on $tag wouldn't return a correct object.

    My tag model relation, as a last resort...

    protected static $_many_many = array(
            'posts' => array(
                'table_through' => 'posts_tags',
                'model_to' => 'Model_Post',
                'cascade_save' => true,
                'cascade_delete' => false
            )
        );

  • One last straw to hold on to:

    couldn't it be that because of the fact that you have two existing objects, none of which has any changes, the "cascade_save = false" on your Posts->Tags relation causes it to skip the entire save operation, which includes inserting the junction record?
  • hmm...

    Tried that here too, but with both cascades set to false, it still inserts the junction record.
  • Yeah, i tried it too. So... I suppose i just could sit in my shower and cry.
  • Is there something top-secret to what you do?

    If not, you can zip your entire install (and a database schema dump if you don't use migrations), and mail it to me (or a link where I can download it), wanwizard<at>fuelphp.com.

    If I can't reproduce it then, I really give up, and blame sun rays...
  • Yeah, sorry... but i don't own the sources and it's pretty secret :/ But thanks for everything anyway.
  • Ah, ok.

    All I can suggest then is to see if you can switch to 1.6.1 for the core and all packages, and see if that solves it.

    Only alternative is to dive into the code of the save() method of orm/classes/manymany.php, and see if you can determine why DB::insert() isn't executed.

Howdy, Stranger!

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

In this Discussion