EllisLab text mark
Advanced Search
2 of 15
2
   
Gas ORM 2
Posted: 21 March 2012 10:32 AM   [ Ignore ]   [ # 21 ]   [ Rating: 0 ]
Joined: 2008-12-11
18 posts

I have to say that i really hate escaping table references \\table within has_many declaration or in other strings :(

 
Posted: 21 March 2012 11:06 AM   [ Ignore ]   [ # 22 ]   [ Rating: 0 ]
Avatar
Joined: 2010-12-20
1590 posts

Setting up your model relationship is one-time set-up, unless in the future, you need to change your table schema smile

 Signature 

“In Code We Trust.”


CI Library : Gas ORM | Proxy

 
Posted: 21 March 2012 12:11 PM   [ Ignore ]   [ # 23 ]   [ Rating: 0 ]
Joined: 2012-03-09
23 posts

@toopay - I could not get the properties to be accessible in the model when set in the view. So I was not able to use Gas\Data(). I did however spend a few hours playing around and figured this out. I think this is a more elegant way to set up the pivot tables, as it’s universal for all my pivot tables and did not require a custom method per pivot table, or a separate entry for each addition.

I still need to do some testing, and I need to add validation to make sure _pivot contains data.

So when creating a record, call function on the model set_pivot. This takes all the table names (lowercase) and the ID if the associated record. Also pass the name of the model, this was just to make the code easier to copy and paste from model to model.

$contents = array(
     
'name' => 'Heal as One',
     
'description' => 'Heal yourself and your pet',
     
'recast' => '20'
    
);

   
$newrecord Model\Skills::make($contents);
   
$newrecord->set_pivot(array(
     
'types' => '3',
     
'pets' => '1',
     
'weapons' => '1',
     
'professions' => '3'
    
), 'skills');


   if(
$newrecord->save()) {
    
echo 'New Record Saved';
   
else {
    
echo 'Foo not saved. Error were '.$foo->errors('<p class="error">''</p>');
   

Then in the model add these private fields -

private $_pivot;
    private 
$_model

The set_pivot function -

function set_pivot($collection$model{
  $this
->_pivot $collection;
  
$this->_model $model;
  return 
$this;
 

Then add this into _after_save() -

if ($this->empty{
   
// Record Id
   
$id $this->insert_id();

   
// Insert Into Appropriate Pivot Tables
   
foreach ($this->_pivot as $key => $value{
    $contents[$key
.'_id'$value;
    
$contents[$this->_model.'_id'$id;
    
$class 'Model\\'.ucfirst($this->_model).'\\'.ucfirst($key);
    
$class::make($contents)->save(TRUE);
    unset(
$contents);
   


  } 

Calling make dynamically could not be done without eval before, but thanks to PHP 5.3 this is now valid.

So now it will insert a new entry for any relations that are provided. Obviously this works for me because I follow the default conventions for naming the pivot table foreign keys. I am sure there is a better way to make this worth with the scheme overrides included in the models.

 
Posted: 21 March 2012 03:07 PM   [ Ignore ]   [ # 24 ]   [ Rating: 0 ]
Joined: 2012-03-09
23 posts

A few questions on finder?

What is the difference between

$skills Model\Skills::all(); 

and

$skills Model\Skills::with('types','professions')->all(); 

When I use either, i still get access to the information regardless if I include With().

I am printing everything as such -

foreach ($skills as $s{
    
echo $s->name.'<br />';
    foreach (
$s->types() as $t){
     
echo $t->name.'<br />';
    
}
    
foreach ($s->professions() as $p{
     
echo $p->name.'<br />';
    
}
    
foreach ($s->weapons() as $w{
     
echo $w->name.'<br />';
    
}    
   } 

So even if weapons are not included, I can still access them? So what does with get me?

Also when I do -

$skills Model\Skills::find(1); 

I can no access any of the relationships (types, professions, weapons, etc).

 
Posted: 21 March 2012 03:31 PM   [ Ignore ]   [ # 25 ]   [ Rating: 0 ]
Avatar
Joined: 2010-12-20
1590 posts
Khrome83 - 21 March 2012 03:07 PM

A few questions on finder?

What is the difference between

$skills Model\Skills::all(); 

and

$skills Model\Skills::with('types','professions')->all(); 

When I use either, i still get access to the information regardless if I include With().

Yes, you will still get access to the related entity without eager load (with method). The different is on the executed queries. With the first one, you actually will generate SELECT statement as many as your records, but with eager load it minimize the query. To find out, try adding this line :

$this->output->enable_profiler(TRUE); 

And try to access the related entity with eager load, and try without it. You will see the different.

Khrome83 - 21 March 2012 03:07 PM

Also when I do -

$skills Model\Skills::find(1); 

I can no access any of the relationships (types, professions, weapons, etc).

What you mean “no access” here?

 Signature 

“In Code We Trust.”


CI Library : Gas ORM | Proxy

 
Posted: 21 March 2012 06:33 PM   [ Ignore ]   [ # 26 ]   [ Rating: 0 ]
Joined: 2012-03-09
23 posts

So it took it down from 220 queries to 7. That is pretty cool.

To answer your question, if I use this code, where the only thing that changed is that all() is replaced with find(1), i get errors.

Code -

$skills Model\Skills::find(1);
   
$this->output->enable_profiler(TRUE); 

   foreach (
$skills as $s{
    
echo $s->name.'<br />';
    foreach (
$s->types() as $t){
     
echo $t->name.'<br />';
    
}
    
foreach ($s->professions() as $p{
     
echo $p->name.'<br />';
    
}
    
foreach ($s->weapons() as $w{
     
echo $w->name.'<br />';
    
}    
    
//wtf($s);

   

Outputs -

A PHP Error was encountered

Severity
Notice

Message
Trying to get property of non-object

Filename
views/welcome.php

Line Number
69



Fatal error
Call to a member function types() on a non-object in /home/guildwar/public_html/application/views/welcome.php on line 70 

 

 
Posted: 21 March 2012 08:42 PM   [ Ignore ]   [ # 27 ]   [ Rating: 0 ]
Avatar
Joined: 2008-09-12
29 posts

Hey toopay,

I searched for this info but with no luck, how can i use Gas ORM 2 with HMCV (Modular Extension) i want to put my models in my modules and not keep them in a folder models in my application folder. How can i do that?

Thank you,
Dan

 Signature 

Portfolio: Daniel Toader

 
Posted: 21 March 2012 09:04 PM   [ Ignore ]   [ # 28 ]   [ Rating: 0 ]
Joined: 2012-03-09
23 posts

On the documentation it lists how to change the folder path for modules.

Not sure if this helps you…

http://gasorm-doc.taufanaditya.com/configuration.html

$config['models_path'= array('Model' => APPPATH.'models'); 

toopay would know better

 
Posted: 22 March 2012 04:18 AM   [ Ignore ]   [ # 29 ]   [ Rating: 0 ]
Joined: 2012-03-22
11 posts

I have a database with tables that have underscores ( _ ) in the name.
In Gas 2 this is apparently interpreted as namespace_tablename, which is fine here, I guess.
But I’m having a bit of a problem with these tables.

For example there is service table which has relationships set up like this:

'resource'     => ORM::has_many('\\Model\\Resource'),
'service_type' => ORM::belongs_to('\\Model\\Service\\Type'), 

Now, if I try

$service->resource() 

I get the resources for that service, but if I try

$service->service_type() 

I get error

You have an error in your SQL syntax
SELECT 
FROM `service_typeWHERE `service_type`.`idIN (%s

so somewhere it bypasses the sprintf().

Am I doing something wrong here?
Should I edit the auto-generated models by hand and make them like \Model\Service_type instead of \\Model\\Service\\Type, or is there something I can do to fix this the way it is now?

I have tried following the User Guide but it doesn’t explicitly tell how to deal with tables like this.

EDIT: It doesn’t work even if I make that change by hand, so the problem is somewhere else. I’m probably doing something stupid here, but it did work with the previous Gas ORM version.

EDIT2: Am I supposed to somehow define the foreign key here? service_type table has a column called id and service has type_id. Is this what breaks it? Why did it work in the previous version though?
I’m actually quite new to databases and ORM, so bear with me here.

 
Posted: 22 March 2012 05:16 AM   [ Ignore ]   [ # 30 ]   [ Rating: 0 ]
Avatar
Joined: 2010-12-20
1590 posts

@Khrome83 and @Dan Tdr

Khrome83 - 21 March 2012 06:33 PM

To answer your question, if I use this code, where the only thing that changed is that all() is replaced with find(1), i get errors.

Code -

$skills Model\Skills::find(1);
   
$this->output->enable_profiler(TRUE); 

   foreach (
$skills as $s{
    
echo $s->name.'<br />';
    foreach (
$s->types() as $t){
     
echo $t->name.'<br />';
    
}
    
foreach ($s->professions() as $p{
     
echo $p->name.'<br />';
    
}
    
foreach ($s->weapons() as $w{
     
echo $w->name.'<br />';
    
}    
    
//wtf($s);

   

Outputs -

A PHP Error was encountered

Severity
Notice

Message
Trying to get property of non-object

Filename
views/welcome.php

Line Number
69



Fatal error
Call to a member function types() on a non-object in /home/guildwar/public_html/application/views/welcome.php on line 70 

 

Obviously, you are trying to itterate object there, not an array. Try :

// Here you are try to find one record
$this->output->enable_profiler(TRUE); 
$skill Model\Skills::find(1);

foreach (
$skill->types() as $t)
{
  
// Do your job with $t here
Dan Tdr - 21 March 2012 08:42 PM

Hey toopay,

I searched for this info but with no luck, how can i use Gas ORM 2 with HMCV (Modular Extension) i want to put my models in my modules and not keep them in a folder models in my application folder. How can i do that?

Thank you,
Dan

Khrome83 already pointed to the right section. For example you have “foo” and “bar” module, located in application/modules, you could have something like this :

$config['models_path'= array(
   
'Model' => APPPATH.'models',
   
'Model\\Foo' => APPPATH.'modules/foo/models',
   
'Model\\Bar' => APPPATH.'modules/bar/models',
); 

If your modules located outside your application folder, just modify the location with an absolute path within your modules.

 Signature 

“In Code We Trust.”


CI Library : Gas ORM | Proxy

 
Posted: 22 March 2012 05:35 AM   [ Ignore ]   [ # 31 ]   [ Rating: 0 ]
Avatar
Joined: 2010-12-20
1590 posts
indCI - 22 March 2012 04:18 AM

EDIT: It doesn’t work even if I make that change by hand, so the problem is somewhere else. I’m probably doing something stupid here, but it did work with the previous Gas ORM version.

EDIT2: Am I supposed to somehow define the foreign key here? service_type table has a column called id and service has type_id. Is this what breaks it? Why did it work in the previous version though?
I’m actually quite new to databases and ORM, so bear with me here.

From information you provide, let say you have it set up this way right now

1. Service entity
  Table name : service
  Model name : Model\Service
2. Service type entity
  Table name : service_type
  Model name : Model\Service_type

In Model\Service

// Because you dont have service_type_id field, 
// you should define the foreign key...
public $foreign_key = array('\\model\\service_type' => 'type_id');

   
//... in relationship declaration
   
'service_type' => ORM::belongs_to('\\Model\\Service_type'), 

In Model\Service_type

//... in relationship declaration
   
'service' => ORM::has_many('\\Model\\Service'), 

 

 Signature 

“In Code We Trust.”


CI Library : Gas ORM | Proxy

 
Posted: 22 March 2012 05:45 AM   [ Ignore ]   [ # 32 ]   [ Rating: 0 ]
Joined: 2012-03-22
11 posts
toopay - 22 March 2012 05:35 AM

From information you provide, let say you have it set up this way right now

1. Service entity
  Table name : service
  Model name : Model\Service
2. Service type entity
  Table name : service_type
  Model name : Model\Service_type

In Model\Service

// Because you dont have service_type_id field, 
// you should define the foreign key...
public $foreign_key = array('\\model\\service_type' => 'type_id');

   
//... in relationship declaration
   
'service_type' => ORM::belongs_to('\\Model\\Service_type'), 

In Model\Service_type

//... in relationship declaration
   
'service' => ORM::has_many('\\Model\\Service'), 

Alright, thanks for the help!

What about the auto-generated version where it’s \Model\Service\Type and not \Model\Service_type?
Does the same apply to that or should it work without defining the foreign key?

 
Posted: 22 March 2012 05:56 AM   [ Ignore ]   [ # 33 ]   [ Rating: 0 ]
Avatar
Joined: 2010-12-20
1590 posts
indCI - 22 March 2012 05:45 AM

What about the auto-generated version where it’s \Model\Service\Type and not \Model\Service_type?

Regarding the auto-generated thing, other member already asked similar questions, and i already explain in this post and this post. Personally, this convention make it easier for me to distinguish a general tables and a pivot tables. If it was within some folder, then it must be a pivot table smile

indCI - 22 March 2012 05:45 AM

Does the same apply to that or should it work without defining the foreign key?

Yes the same apply, except, you may need to also specify the table name on Model\Service\Type :

public $table 'service_type'
 Signature 

“In Code We Trust.”


CI Library : Gas ORM | Proxy

 
Posted: 22 March 2012 07:16 AM   [ Ignore ]   [ # 34 ]   [ Rating: 0 ]
Joined: 2012-03-22
11 posts

Another thing, I had to retrieve records that match a datetime BETWEEN two datetimes and a certain foreign key.
In the last version I used

$this->find_where'starting BETWEEN "' $date '" AND "' $to_date '" AND resource_id=' $resource_id ); 

I’m not sure if that was best practice but it worked.
There doesn’t seem to be a find_where method in Gas 2 though.
How should I achieve this?

EDIT: Ah, figured it out. If anyone needs it, here’s how I wrote it now. (Unless there’s a better way to do it.)

ModelName::where'starting BETWEEN "' $date '" AND "' $to_date '"' )->find_by_resource_id$resource_id ); 

EDIT2: Scratch that. It did not work it just translated to this. Still don’t know how to do it.

SELECT FROM (`ModelName`) WHERE `resource_id` =  

EDIT3: Alright I put it in a single CI AR query, so that works at least, but shouldn’t find_by_column be chainable with them? Or is all() the only gas method that’s chainable with CI query builder?

ModelName::where'starting BETWEEN "' $date '" AND "' $to_date ' 23:59:59" AND resource_id=' $resource_id )->all(); 
 
Posted: 22 March 2012 08:37 AM   [ Ignore ]   [ # 35 ]   [ Rating: 0 ]
Avatar
Joined: 2008-09-12
29 posts
toopay - 22 March 2012 05:16 AM

@Khrome83 and @Dan Tdr

Dan Tdr - 21 March 2012 08:42 PM

Hey toopay,

I searched for this info but with no luck, how can i use Gas ORM 2 with HMCV (Modular Extension) i want to put my models in my modules and not keep them in a folder models in my application folder. How can i do that?

Thank you,
Dan

Khrome83 already pointed to the right section. For example you have “foo” and “bar” module, located in application/modules, you could have something like this :

$config['models_path'= array(
   
'Model' => APPPATH.'models',
   
'Model\\Foo' => APPPATH.'modules/foo/models',
   
'Model\\Bar' => APPPATH.'modules/bar/models',
); 

If your modules located outside your application folder, just modify the location with an absolute path within your modules.

Thanks for the reply, the thing is that i can`t add every single module in the config path because i want to allow users to develop/add modules of their own, and that would mean that the path would have to change every time someone ads a module, can’t it be done like gas orm 1.x done it? give it a folder and search for models in that folder? Or is there any other way to do this?

Thanks

Edit 1:

i added in config/gas.php, created the models with gas orm

$config['models_path'= array(
//'Model' => APPPATH.'models',
'Model\\News' => APPPATH.'modules/news/models'
); 

and i am trying to access it from the news controller:

public function migrate(){
// FINDER  
$all_users Model\News::all();
var_dump($all_users);

and i get this in my error log

[b][22-Mar-2012 12:45:11 UTC] PHP Fatal error:  Class 'Model\News' not found in /home/bogdan/public_html/beta/system/cms/modules/news/controllers/news.php on line 81[/b] 

what am i doing wrong?

Thanks

 Signature 

Portfolio: Daniel Toader

 
2 of 15
2