EllisLab text mark
Advanced Search
12 of 15
12
   
Gas ORM 2
Posted: 28 October 2012 02:27 PM   [ Ignore ]   [ # 171 ]   [ Rating: 0 ]
Joined: 2011-08-11
3 posts

@toopay; Thanks for your reply.

I’m using the following models (simplified version);

Model 1 (Company);

<?php namespace Model;

use 
\Gas\Core;
use 
\Gas\ORM;

class 
Company extends ORM {

 
public $primary_key 'id';


 function 
_init()
 
{
 
  
// Define relationships
  
self::$relationships = array(
   
'businessunit' => ORM::has_many('\\Model\\Businessunit')
  );
  
  
self::$fields = array(
   
'id' => ORM::field('auto[10]'),
   
'name' => ORM::field('char[200]'),
   
'created_at' => ORM::field('datetime'),
   
'modified_at' => ORM::field('datetime'),
  );

 
}

Model 2 (Businessunit);

<?php namespace Model;

use 
\Gas\Core;
use 
\Gas\ORM;

class 
Businessunit extends ORM {
 
 
public $primary_key 'id';

 function 
_init()
 
{
  self
::$relationships = array (
   
'company' => ORM::belongs_to('\\Model\\Company')
  );
  
  
self::$fields = array(
   
'id' => ORM::field('auto[10]'),
   
'name' => ORM::field('char[200]'),
   
'created_at' => ORM::field('datetime'),
   
'modified_at' => ORM::field('datetime'),
  );

 
}

The businessunit database table has a field company_id.

The controller;

class Test extends CI_Controller {
 
 
public function __construct() {
  parent
::__construct();
  
//$this->output->enable_profiler(TRUE);
  
 
 
}
 
 
public function index(){

    $companies 
Model\Company::all();
    
    
print_r($companies);
 
 
}

But isn’t it an php fundamental instantiating an abstract class is illegal?
From the php manual:

Classes defined as abstract may not be instantiated,....

http://php.net/manual/en/language.oop5.abstract.php

Or is it not the intention to instantiate “gas/orm”? I think it is happening in line 830;
$gas = self::make();

If i get it right, this line results in the instantiation of “abstract class ORM” (which is illegal?).

 
Posted: 28 October 2012 06:55 PM   [ Ignore ]   [ # 172 ]   [ Rating: 0 ]
Avatar
Joined: 2010-12-20
1590 posts

I think we have PHP version incompatible issue here. make method is returning new static, so we’re not trying to instantiate the abstract. Here you could see the analog assertion on how late static binding works, on supported php environment(5.3++) : http://codepad.viper-7.com/cuGBre

What are your php version btw?

 Signature 

“In Code We Trust.”


CI Library : Gas ORM | Proxy

 
Posted: 29 October 2012 09:13 AM   [ Ignore ]   [ # 173 ]   [ Rating: 0 ]
Joined: 2011-08-11
3 posts

Hi Toopay,

phpinfo: PHP Version 5.3.3-7+squeeze14

The example you provided is working fine..
Your example is valid for calls from child classes like; Company::all().

But it goes wrong for calls like to abstract class directly like ORM::has_many(). Which occur in the models for defining the relationships.

Isn’t it this what’s happening?;

<?php
Abstract class ORM
{

 
final public static function make($record = array())
 
{
  
return new static($record);
 
}
 
 
public static function __callStatic($name$arguments)
 
{
  $gas 
self::make();
 
}
 
}

print_r
(ORM::has_many()); //Results in the error

?> 

http://codepad.viper-7.com/Z8OQLY

 
Posted: 31 October 2012 03:47 PM   [ Ignore ]   [ # 174 ]   [ Rating: 0 ]
Avatar
Joined: 2010-12-20
1590 posts

@erikver :
As you can see, ORM::has_many is a static call, and it supposed to not require any instantiation if it was called via object context.

Here i try to emulate the full life-cycle of relationships initialization in any model sub-classes : http://codepad.viper-7.com/xxfrom , notice that the override method is calling relationships method on ORM, which is a static method without any abstract instantiation: its a valid call.

 Signature 

“In Code We Trust.”


CI Library : Gas ORM | Proxy

 
Posted: 01 November 2012 05:38 AM   [ Ignore ]   [ # 175 ]   [ Rating: 0 ]
Joined: 2012-11-01
5 posts

I have two tables. One with events and one with several performances to specific events. I want to list all my events ordered by the performance with the closest date. Is this possible? Thanks.

 
Posted: 05 November 2012 07:37 PM   [ Ignore ]   [ # 176 ]   [ Rating: 0 ]
Joined: 2012-11-05
7 posts

Hey, loving Gas, it works great.  The first ORM I’ve used.

I haven’t been able to find any documentation about self-referencing models with Gas.  I have a hierarchy of categories connected by a pivot table (category table is `category`, pivot table is `category_category`.  Haven’t been able to figure out how to set up the relationship between the two, as the foreign keys are different (obviously), but the models are the same, so this wouldn’t work:

[application/models/category/category.php]

class Category extends ORM
{
    
public $foreign_key = array('\\model\\category' => 'category_id''\\model\\category' => 'parent_category_id');

    public function 
_init()
    
{
        self
::$relationships = array(
            
'category' => ORM::belongs_to('\\Model\\Category'),
            
'parent'  => ORM::belongs_to('\\Model\\Category'),
        );

        
self::$fields = array(
            
'id'                    => ORM::field('auto'),
            
'category_id'           => ORM::field('int'),
            
'parent_category_id'    => ORM::field('int'),
        );
    
}

Advice?  Is this possible?

 
Posted: 05 November 2012 08:40 PM   [ Ignore ]   [ # 177 ]   [ Rating: 0 ]
Joined: 2012-11-05
7 posts

Another issue I’ve run into is trying to more complex queries when getting related objects.  For example, say I want to select all parent categories that were created before a certain date.  I tried chaining Active Record methods before the relationship method call, but it had no effect.  The only way to affect the results seem to be the simple “select:”, “limit:”, and “order_by:” arguments.  How can this be done?

P.S. I’d be happy to write up documentation for these scenarios for the site.

 
Posted: 05 November 2012 11:23 PM   [ Ignore ]   [ # 178 ]   [ Rating: 0 ]
Joined: 2012-11-05
7 posts

Hi Toopay,

This is really great software grin

Is it possible to eager load related models on either side of a relationship?  I’m loading a child relation, then trying to access it’s parent, but I get the following error.

A PHP Error was encountered
Severity
Warning
Message
in_array() expects parameter 2 to be array, boolean given
Filename
classes/core.php
Line Number
1588 

Line 1588 being the first line in the block below from core.php:

elseif (in_array($matcher_id$holder->get($token.$original_id)))
{
  
// We have assoc ids to check against it
  
if (isset($fk_original_ids))
  
{
    $matched_id[$fk_original_ids[$original_id]][] 
$child_instance;
  
}
  
else
  
{
    $matched_id[$original_id][] 
$child_instance;
  
}  

With the change from this post about the bug for using with::(‘example’)->all();

The child model is:

<?php namespace Model;

use 
\Gas\Core;
use 
\Gas\ORM;

class 
Lkpsite extends ORM {
 
 
public $primary_key 'site_code';
 public 
$foreign_key = array('\\model\\lkpstaff' => 'manager_refid');

 function 
_init()
 
{
  self
::$relationships = array(
    
'manager' => ORM::belongs_to('\\Model\\Lkpstaff'),
  );

  
self::$fields = array(
   
'site_code' => ORM::field('string'),
   
'manager_refid' => ORM::field('numeric[4]'),
   
'project_name' => ORM::field('string'),
  );
 
}

And the parent model is:

<?php namespace Model;

use 
\Gas\Core;
use 
\Gas\ORM;

class 
Lkpstaff extends ORM {
 
 
public $primary_key 'staff_refid';

 function 
_init()
 
{
  self
::$relationships = array(
   
'site' => ORM::has_many('\\Model\\Lkpsite'),
  );

  
self::$fields = array(
   
'staff_refid' => ORM::field('numeric[4]'),
   
'first_name' => ORM::field('string'),
   
'second_name' => ORM::field('string'),
   
'office' => ORM::field('string'),
  );
 
}

Loading the parent model first works fine with the following :

$data['staff'Model\Lkpstaff::with('site')->all(); 

But when I try this instead:

$data['sites'Model\Lkpsite::with('manager')->all(); 

It produces the error about a boolean rather than an array value.

Looking at what’s being passed in where the array should be, $token is the child relation model name (lkpsite), then the foreign key (manager_refid), which matches with an entry in $holder, but for $original_id it is passing in the child relation’s primary key value, so it doesn’t match up with the foreign key values the $token points towards.  I’m using the most recent CI download, and took the Gas ORM files from github today.

I’m not sure what’s going on, or if it’s even meant to work this way, so any help will be appreciated, thanks

 
Posted: 06 November 2012 05:12 AM   [ Ignore ]   [ # 179 ]   [ Rating: 0 ]
Joined: 2012-11-01
5 posts

I’m having a problem solving the relationship between two tabels: events and event_images. The event_images table has an events_id and the models looks like this:

<?php namespace Model;

use 
\Gas\Core;
use 
\Gas\ORM;

class 
Events extends ORM {

 
public $primary_key "id";

 public function 
_init() {

  self
::$relationships = array(
   
"venue"   => ORM::belongs_to("\\Model\\Venues"),
   
"image"   => ORM::has_one("\\Model\\Event_images"),
   
"performances" => ORM::has_many("\\Model\\Event_performances")
  );

  
self::$fields = array(
   
"id"   => ORM::field("auto[10]"),
   
"venues_id"  => ORM::field("INT[11]"),
   
"name"   => ORM::field("CHAR[155]", array("required")),
   
"urlname"  => ORM::field("CHAR[155]", array("required")),
   
"description" => ORM::field("string", array(), "TEXT"),
   
"active"  => ORM::field("INT[1]")
  );
 
}

AND

<?php namespace Model;

use 
\Gas\Core;
use 
\Gas\ORM;

class 
Event_images extends ORM {

 
public $primary_key "id";

 public function 
_init() {

  
//Relationships to other tables
  
self::$relationships = array(
   
"event"  => ORM::belongs_to("\\Model\\Events")
  );

  
//Fields in our DB table
  
self::$fields = array(
   
"id"   => ORM::field("auto[10]"),
   
"events_id"  => ORM::field("INT[11]", array("required")),
   
"name"   => ORM::field("CHAR[10]", array("required")),
   
"ext"   => ORM::field("CHAR[5]", array("required")),
   
"width"   => ORM::field("INT[5]", array("required")),
   
"height"  => ORM::field("INT[5]", array("required")),
   
"mime"   => ORM::field("CHAR[10]"),
   
"path"   => ORM::field("CHAR[255]", array("required"))

  );
 
}

I’m trying to fetch all events with the image that belongs like this:

$events Model\Events::with("image")->all();
foreach(
$events as $row{

 
echo $row->name."<br>";
 
 echo 
"<pre>";
 
print_r($row->image());
 echo 
"</pre>";

But the only event that fetches an image is the last row of the loop. It works if I skip the with statement but it’s alot slower..

 
Posted: 06 November 2012 05:45 AM   [ Ignore ]   [ # 180 ]   [ Rating: 0 ]
Avatar
Joined: 2010-12-20
1590 posts

@snowfall and @necken, there was a discussion about eager load with ‘all’ method issue previously. Try this patch class : https://gist.github.com/4023670 (replace your core.php under third_party/gas/classes/core.php with those patch). Let me know if you two, still have any issues with eager loading afterward.

@jonahdahlquist, If you need self-referencing to some entity, you actually could do it without adding more complexity within your model definition. How? Just write something like :

/** 
 * Method for fetching child categories 
 * 
 * @return array 
 */
public function category()
{
  
return self::find_by_parent_category_id($this->id);
}

/** 
 * Method for fetching parent category
 * 
 * @return object
 */
public function parent()
{
  
return self::find($this->parent_category_id);

As for your request regarding additional query for child entities, there is no support for ‘where’ or other clause than ‘select’, ‘limit’, and ‘order_by’ for version 2.x.x. Maybe for the next major version.

 Signature 

“In Code We Trust.”


CI Library : Gas ORM | Proxy

 
Posted: 06 November 2012 07:12 AM   [ Ignore ]   [ # 181 ]   [ Rating: 0 ]
Joined: 2012-11-05
7 posts

Hi Toopay,

I had already made the change to core.php, I tried using the core.php you linked to in case there were other changes but it still doesn’t work. 

With the code I posted you can see that the all() method works one way along the relationship with the patch, but not the other.  I put the behaviour that’s failing also at the bottom of the post, where with

$token.$original_id 

$token points towards the correct values in $holder

lkpsite:manager_refid 

However $original_id points towards the primary key value (a site_code value), and not the foreign key value (a manager_refid value) which would produce an array result.

Thanks for the help smile

 
Posted: 06 November 2012 02:42 PM   [ Ignore ]   [ # 182 ]   [ Rating: 0 ]
Avatar
Joined: 2010-12-20
1590 posts
snowfall - 06 November 2012 07:12 AM

However $original_id points towards the primary key value (a site_code value), and not the foreign key value (a manager_refid value) which would produce an array result.

Gotcha. I’ve just update the previous patch for core.php : https://gist.github.com/4023670

 Signature 

“In Code We Trust.”


CI Library : Gas ORM | Proxy

 
Posted: 06 November 2012 04:23 PM   [ Ignore ]   [ # 183 ]   [ Rating: 0 ]
Joined: 2012-11-05
7 posts

@toopay

Thanks for the reply.  The issue with the category model is that the relationships are in a separate table, so I can’t query the category table directly.  Each category can have multiple parents, and multiple children

 
Posted: 06 November 2012 04:26 PM   [ Ignore ]   [ # 184 ]   [ Rating: 0 ]
Joined: 2012-11-05
7 posts

@toopay

And if there’s no way to modify the query on the foreign table through the pivot table, how would you recommend I execute a more complex query on it?  I guess I’ll have to bypass the built-in relationship functionality.

Thanks

 
Posted: 06 November 2012 05:54 PM   [ Ignore ]   [ # 185 ]   [ Rating: 0 ]
Joined: 2012-11-05
7 posts

Is there a way to chain multiple where() clauses together?  I’ve tried it, but only the last clause is in the query.

$categories \Model\Categories::make()->where('priority >'2)->where('author'482)->all();
// Will only run 'SELECT * FROM category WHERE author = 482' 
 
12 of 15
12