Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Associations (Relationships) in Active Record
  • How do I access relationships once I have retrieved a record? Is it like Kohana, where the alias i provided when defining the relationship becomes a property of that object? For example:
    protected $_has_many = array('somethings' => array('model' => 'User_Something'));
    
    $user = Model_User::find_by_username_and_password('ben', 'password');
    
    $user->somethings->find_all()
    
  • Have a look here as well regarding relations: http://www.fuelphp.com/forums/topics/view/157 jschreuder: How much will the AR change? Everything works fine for me at the moment but one thing, using AR inside modules access relations outside module. I keep getting Exceptions. Any clue? It looks like the \ is missing. The following works fine:
    // app/modules/news/classes/model/newsletter.php
    
    namespace News;
    
    class Model_Newsletter extends \ActiveRecord\Model {
        protected $belongs_to = array('language');
    }
    
    // app/modules/news/classes/model/language.php
    
    namespace News;
    
    class Model_Language extends \ActiveRecord\Model {
        protected $has_many = array('newsletters');
    }
    
    // app/modules/news/classes/controller/newsletter.php
    
    namespace News;
    
    class Controller_Newsletter extends \Controller_Template
    {
        function action_router($method, $params)
        {
            $options = array('include' => array('language'));
            $newsletter = Model_Newsletter::find_first_by_newsletter_code($method, $options);
            echo $newsletter->language->language_code;
        }
    }
    
    // or
    
    class Controller_Newsletter extends \Controller_Template
    {
        function action_router($method, $params)
        {
            $newsletter = Model_Newsletter::find_first_by_newsletter_code($method);
            echo $newsletter->language->language_code;
        }
    }
    
    

    But when I have for example, the language relation as follows:
    // app/classes/model/language.php
    
    class Model_Language extends ActiveRecord\Model {
        protected $has_many = array('newsletters');
    }
    
    

    ErrorException [ Warning ]: call_user_func_array() expects parameter 1 to be a valid callback, class 'Language' not found It looks like the namespace (module) is not propper applied. Or is the code above not right?
  • Nevermind, the above works perfect! It would be not logical to use other AR models outside a module. I hope the AR does not change much because everything works fine, you just have to know how... Even accessing an included table is easy. Including is not needed if you have applied the $belongs_to correct ;-) BUT you HAVE to include when using where for the included table (languages).
    // app/modules/news/classes/controller/newsletter.php
    
    namespace News;
    
    class Controller_Newsletter extends \Controller_Template
    {
        function action_router($method, $params)
        {
            $options = array(
                'include' => array('language'), // not needed if $belongs_to is set in Model
                'where' => array(
                    array('languages.language_code', '=', 'nl')
                )
            );
            $newsletter = Model_Newsletter::find_first_by_newsletter_code($method, $options);
            echo $newsletter->language->language_code;
        }
    }
    
    

  • If anyone is interested in using Kohana's ORM in the meantime, see http://fuelphp.com/forums/topics/view/263
  • @Mike AR works fine as long as you don't use has-many-through or try configuring models too much, it works fine when you keep to convention. But that's also the problem with it, our main philosphy is that everything should be configureable - conventions are nice to make things work quickly, but configuration should take precedence.
    It is possible by the way to use models from (other) modules, but I don't recommend it at this point. I don't know how much it will change. I started a full rewrite which kept some things similar but did change some stuff. I have since turned my code over to Dan who intended to take parts of it and do his own rewrite, and we'll have to wait what he comes up with.
  • Basically, is it done like Kohaana's ORM: (see http://kohanaframework.org/guide/orm/relationships for more)
    protected $_belongs_to = array('[alias name]' => array('model' => '[model name]', 'foreign_key' => '[column]'));
    
  • hello, I'm not familiar with stuff you're asking, but here is simple belongs_to example: http://scrp.at/3f1c02ec41743dbdd26f221caaab12a22d8d7fdl
  • hey, thanks for that link but i've already got that far. say for example, i've got two models. they are:
    order
    

    and
    order_item
    

    In kohana, i say in relationships:
    protected $_has_many = array('items' => array('model' => 'Order_Item'));
    

    so i call the relationship by the alias (items) - eg $order->items->find_all(); but in Fuel I'm not sure how to assign these relationships, i'd have to call $order->order_items to get the items. the reason items is under order is because i put the model for items under a folder called order in the model folder. confusing much? but the reason is that it follows the same schema as the database. (tables would be orders, and order_items respectively). it all ties in with autoloading classes etc. many platforms do this, such as magento (where you might see catalog, and catalog_product, catalog_product_entity). in Kohana it's a synch but in Fuel i can't do it... yet. I've got a couple of projects lined up and i need this to work before i can start (i really want to use fuel but kohana is looking like it's gonna be the winning contender). when dan's back home maybe the docs will go up :). can't wait for it though
  • Just drop the ->find_all() and that should work fine.
  • Yeah it doesn't work. when i add a relationship it doesn't recognise the alias in the structure i used before - it only uses the value part of the array instead of taking the alias from the key part - it doesnt use foreach ($something as $key => $value); might have to import kohana's ORM and just add the __callStatic() methods in?
  • Ben, Even though we do use some pieces of it, we're not copying Kohana. And copying Kohana is not the solution to every time something isn't documented yet, or doesn't work like Kohana. If you want the latter: use Kohana. As is mentioned clearly we're still in early beta and we've already come a long way towards documenting everything, but it will be a bit until we get the whole thing done. In the meantime: help us out by contributing if you can.
    But just suggesting to us to use Kohana classes as replacements for the stuff we've written already but not documented isn't helping anyone.
  • Jelmer, It's not that it's not documented, it's just that it doesn't work. The way the ActiveRecord classes are setup won't allow for complex database structures. I'm not trying to be a smartass but rather merely pointing out that maybe the way it works could be looked at in a different way. I love the way fuel's ActiveRecord works alot, just take a second to look at the following example and maybe you'll see what i'm saying. In reference to this image, Say in my model I've got a model called sales_flat_invoice (located at models/sales/flat/invoice.php Now in it's associations I have the following:
    protected $has_many = array('sales_flat_invoice_comment', 'sales_flat_invoice_item');
    

    etc... Now let's load a record:
    $invoice = Model_Sales_Flat_Invoice:find_by_name('Ben Corlett');
    
    That is fine :) Now, let's find a comment:
    $comment_text = $invoice->sales_flat_invoice_comment->text;
    

    Now I run into three problems here:
    1.
    
    ErrorException [ Warning ]: call_user_func_array() expects parameter 1 to be a valid callback, class 'Model_SalesFlatInvoiceComment' not found - It's camel-casing when looking for models.
    2.
    
    The property name get's quite lengthy.
    3.
    
    Even if it did find it, it would be looking for a foreign key that is Sales_Flat_Invoice_id (as we can't specify the foreign key for this relationship) Let's say I could setup the assocations by doing the following:
    protected $has_many = array('comments' => array('model' => 'Sales_Flat_Invoice_Item', 'foreign_key' => 'invoice_id');
    

    That is the only limitation this activerecord class has and if it could surpass this it would be amazing. Unless you know of a way to achieve this with the current setup? EDIT: these tables are out of magento and I'm aware that they would need to be pluralised if used in this orm (unless configured differently. they're purely for example's sake)
  • It's not yet finished. I'm quite aware of the limitations which is why I made php.activerecord available today as a package which can be installed using Oil:
    php oil package install phpactiverecord
    
    Our own AR will probably get a partial or even full rewrite. I've done some work not yet committed already to make our AR more flexible. I can say AR will change, I can't say yet how much but we'll probably keep it mostly backwards compatible.
  • Having looked at the activerecord class i found that you can use an alias, but not set a primary key (haven't tested this). see line 268 in packages/activerecord/model.php
    foreach ($this->{$type} as $assoc)
        {
         /* handle association sent in as array with options */
         if (is_array($assoc))
         {
          $key = key($assoc);
          $this->{$key} = new $class_name($this, $key, current($assoc));
         }
         else
         {
          $this->{$assoc} = new $class_name($this, $assoc);
         }
        }
    

    looks like it sets the key as the relationship, the value as the class to load, meaning
    protected $has_many = array('test' => 'Model_Test');
    

    should work, but
    protected $has_many = array('test' => array('model' => 'Model_Test'));
    

    won't (as the value part is an array containing more info. so we'd only need to modify this function and whatever will set the foreign key).

Howdy, Stranger!

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

In this Discussion