Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Extra property in Many to Many relation
  • Hi there, I have two tables products and accessories, relation many to many through table products_has_accessories, which has following fileds: product_id, accessory_id and is_included. Is there any easy way how to access property is_included from the Model? Thanks. OT: Text formatting doesn't work. (Chrome 16.0.912)
  • Laravel Eloquent ORM solved this problem in a nice way: http://laravel.com/docs/database/eloquent#intermediate-tables
  • You can do the same in FuelPHP's ORM by defining a model for the relationship table, so it becomes an object like all others... So instead of
    Model_A has_many Model_B, Model_B has_many Model_A
    
    you will have
    Model_A has_many Model_AB, Model_AB belongs_to Model_A,
    Model_B has_many Model_AB, Model_AB belongs_to Model_B
    
  • Hey TreeNode - I have the exact same issue. I'm trying to set up a many-to-many through a table that has one additional column, which I want to use in a where condition.
    protected static $_many_many = array(
      'coordinators' => array(
        'table_through' => 'neighborhood_volunteers',
        'key_from' => 'id',
        'key_through_from' => 'neighborhood_id',
        'key_to' => 'id',
        'key_through_to' => 'user_id',
        'model_to' => 'Model_User',
        'conditions => array( 'where' => array( array( 'neighborhood_volunteers.is_coordinator', '=', 1) ) )
      )
    );
    

    And I'm getting a column not found error : Column not found: 1054 Unknown column 'neighborhood_volunteers.is_coordinator' in 'on clause'... I saw your post and got excited, but I tried 'coordinators_through.is_coordinator.' And that didn't work either. Did referencing display_order as items_through.display_order really fix it for you? Am I misinterpreting how to translate this to my situation? Help please! :)
  • Bump. Looking for the same info, thanks!!
  • Not possible because there wouldn't be an object to assign the property to. It is however possible to fetch a relation, the object in between and the relation belonging to that one. Which is basicly the same as a many-many but with an object in between instead of fetching the many directly. Check out nested relations in the docs.
  • I tried putting in where conditions on the link table in my code, such as you have above, but I received errors as well. My issue was kinda specific to the order by condition and has some additional issues (https://github.com/fuel/orm/issues/134). You will not be able to return the data in the linked tables without making it into it's own model, that's one suggestion that might clear up a lot of your issues. That way you can reference the linked table by the model name in your conditions. So, a new model named neighborhood_volunteers, and update your relationships in the other models to relate to the new model and no longer directly to each other. Depending on what you're doing, it's possible to keep the condition out of the relationship description, and just put it into your query. You can actually reference the link table this way using the "coordinators_through.is_coordinator". Something like $coordinators = Model_Coordinator::query->related('neighborhood')->where('coordinators_through.is_coordinator', '=', '1')->get(); I've tested this and it works. If anything, I'm reading it backwards so it might be "neighborhood_through".
  • Yep, that was the way I was thinking to go about it, but before I do... is there any way to reference the link table in a many-to-many relationship, when describing the relationship in the model? For example...
    Main table Shops links to table Items through shops_items. Shops_items contains the index values of Shops and Items, as well as a value "display_order". protected static $_many_many = array(
    'items' => array(
    'table_through' => 'shops_items',
    'key_through_to' => 'item_id',
    'conditions' => array(
    'order_by' => array('shops_items.display_order')
    )
    )
    );
  • Thanks for your help - much appreciated! I decided to set up a model for the link table and relate the two models to that one.
  • I might have found the solution to my last question. Instead of shops_items, I would have to reference it as items_through:
    protected static $_many_many = array(
    'items' => array(
    'table_through' => 'shops_items',
    'key_through_to' => 'item_id',
    'conditions' => array(
    'order_by' => array('items_through.display_order')
    )
    )
    );
  • Is there full example of that type of relationship on the net? I don't know how can I query all B objects related with A from A model and from inverse side
  • It isn't a special relationship, so there's nothing special about implementing it.

    You only have to realise that a many-many relation with a through table is, from a database normalisation point of view, only a combination of two one-to-many relations.

    To query it, instead of using A->related('B'), you do A->related('AB')->related('AB.B') to include both objects in the query.

    For access it's similar, instead of  foreach (A->B as $b), you do foreach(A->AB as $ab) { $b = $ab->B }, which works because every AB only has a single B.
  • I have 3 models: Model_User, Model_Shop and Model_UserShop (<- fuelphp want to have primary key on this model - what about it?) and relations as follows:
    Model_User has many Model_UserShop
    Model_Shop has many Model_UserShop
    Model_UserShop belongs_to Model_User and belongs_to Model_Shop

    I the controller I want to get all Users for Model_Shop::find($id) throught Model_UserShop, how can I do this query in the fuelphp? I try $shop = Model_Shop::find($id, array('related' => array('usershops'))); but in the $shop var in the relation section I have strange [[ ]] signs and only one user, but in the database I have two... what's going on, could you help me?
  • A models should have a primary key. It's by design, it's the only way to uniquely identify an object.

    With this query, $shop should contain one instance of Model_Shop, containing the object identified by $id.

    You can access the relational model using $shop->usershops, which is an array of Model_Usershop objects because of the has_many relation. You can iterate over this to access the individual usershop objects:

    foreach ($shop->usershops as $usershop)
    {
        // assuming the belongs_to to Model_User is called 'user'
        var_dump($usershop->user);
    }
  • thanx, I'm trying this just like that and its strange behaviour, beacause in the database I have two rows with the same shop_id in the Model_UserShop, but the var_dump shows only first...
  • The problem was in the location of class for Model_UserShop, I have to rename it to Model_User_Shop and saved it in the model/user/shop.php file, before it was in the model directory and named usershop.php :) Now all works fine, fuelphp is the best php framework I've used :) like rails

Howdy, Stranger!

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

In this Discussion