Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Regarding insert into many-to-many through-table
  • Hi there,

    I'm a beginner at PHP and MVC frameworks. I have two models, 'users' and 'books'. It is a many-to-many relationship and I have a through-table 'books_users'. I wish to create a function in the model (I'm guessing it would be the 'users' model) to allow users to 'subscribe' to books. I've read this and this.

    Can someone explain the following (taken from the latter link) lines to me, especially the part about the numbers used:

    // both main and related object already exist
    $user = Model_User::find(8);
    $user->posts[1] = Model_Post::find(1);
    $user->save();


    I've come up with this:

    Model_User::find(2)->books[2] = Model_Book::find(2)


    But upon printing the array in 'oil' console, I don't find any details about the 'user'. What am I doing wrong?

    Thanks for your time.
  • $user = Model_User::find(8);  //means find user with primary key 8. 
    // to access users and books go to your user model and add the following to define the relationship
    protected static $_has_many = array('books' => array(
        'model_to' => 'Model_Book',
        'key_from' => 'id', //primary key in user table    'key_to' => 'user_id', //referenced key in books table    'cascade_save' => FALSE,    'cascade_delete' => TRUE,    // there are some more options for specific relation types),);

    //to be able to access records lets say user with primary key 2

    $user = Model_User::find(2); 
    echo $user->id; //will bring out user id;
    //to access books user has
    $books=$user->books; //will give you a handle on the books 
    i hope this was helpful


  • I'm sorry if I wasn't clear. I already know how to get the 'books' for a certain 'user'. What I would like to know is how I can add a 'book' to a certain 'user'.

    And also, what the following, means:

    $user->posts[1] = Model_Post::find(1);
  • That is not correct, it should be
    $user->posts[] = Model_Post::find(1);
    assuming the relation from users to posts is called 'posts'. So this line says "Assign the result of the find operation to the many relation between users and posts.

    If it were a "one" relation, it would have been
    $user->posts = Model_Post::find(1);
    so without the array brackets.

    After this, don't forget to save $user, otherwise the relations will not be updated.
  • Thanks so far. This is what I have now in my main/book controller:

    public function action_subscribe($book_id) {
    if (Auth::check()) {
    $user = Model_User::find(Auth::get('id'));
    $book = Model_Book::find($book_id);
    $user->books[] = Model_Book::find($book_id);

    if ($user and $user->save()) {
    Session::set_flash('success', e('Added book #' . $book->id . ' to your subscriptions.'));
    }
    else {
    Session::set_flash('error', e('Could not add book to your subscriptions'));
    }
    }
    else {
    Response::redirect('member/login');
    }
    }


    But it is saving the values in reverse. I mean the user_id is stored in the book_id column and vice versa. Any idea what could be wrong?
  • HarroHarro
    Accepted Answer
    I'd say your relationship definition, because that is where it gets the column names from.
  • As far as I know; after reading the last part of Many-to-many relations, my relationship definitions are correct.

    Here is what I have in my 'book' model:
    protected static $_many_many = array(
    'users' => array(
    'key_from' => 'id',
    'key_through_from' => 'book_id', // column 1 from the table in between, should match a books.id
    'table_through' => 'books_users', // both models plural without prefix in alphabetical order
    'key_through_to' => 'user_id', // column 2 from the table in between, should match a users.id
    'model_to' => 'Model_User',
    'key_to' => 'id',
    'cascade_save' => true,
    'cascade_delete' => false,
    )
    );


    And here is what I have in my 'user' model:
    protected static $_many_many = array(
    'books' => array(
    'key_from' => 'id',
    'key_through_from' => 'book_id', // column 1 from the table in between, should match a books.id
    'table_through' => 'books_users', // both models plural without prefix in alphabetical order
    'key_through_to' => 'user_id', // column 2 from the table in between, should match a users.id
    'model_to' => 'Model_Book',
    'key_to' => 'id',
    'cascade_save' => true,
    'cascade_delete' => false,
    )
    );


    Is there something wrong with these definitions? It seems to work fine when I want to view all the books for a certain user though.


    UPDATE: Alhamdulillah, I was able to solve the problem. The answer lied in switching 'key_through_from' with 'key_through_to' in the models.

Howdy, Stranger!

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

In this Discussion