Part of the EllisLab Network
   
3 of 53
3
DataMapper ORM v1.8.0
Posted: 22 January 2011 07:15 AM   [ Ignore ]   [ # 21 ]  
Summer Student
Avatar
Total Posts:  16
Joined  02-12-2010

Hello all,
I am new in CodeIgniter and also Datamapper. I plan to use HMVC with Datamapper, so all the datamase ORM model will be placed in each module. For example, user.php is saved under users module’s model folder, and group.php is saved under groups module’s model folder.

But it came with a problem when I try to set relationshop with $has_many and $has_one, and call it from any modules, for example:

$u = new User();
$u->group->get(); 

It said that Group class cannot be found. I know the solution, which is loading the file. So, i manually place load method from HMVC before class line, for example:

Modules::load_file('user'APPPATH.'modules/users/models/')// here will load the file

class Group extends DataMapper {
  
var $has_many = array(
    
'user' => array(
      
'class' => 'user',
      
'other_field' => 'group'
  
));

  var 
$validation = array(
    
'title' => array(
      
'rules' => array('required''trim''min_length' => 4'max_length' => 45'unique'),
      
'label' => 'Username'
    
),
    
'description' => array(
      
'rules' => array('required''trim''min_length' => 4,'max_length' => 255),
      
'label' => 'Email'
    
)
  );

I have to write the load method in both of related files (user.php and group.php) in order to make it works.

So, the problem is fixed. But it will be hard if I need to create other modules that will be related to other modules too, I have to write in every files related in each modules.

I have an idea to make it compatible with HMVC, such as make it available to find other ORM Class in other module based on $has_one or $has_many properties, for example:

$has_one = array(
  
'user' => array(
    
'class' => 'user',
    
'module' => 'users'
  
)
); 

Yeah, something like that, and it will look on module firstly. But i don’t know how to write it in Datamapper class. Any idea?

 Signature 

Haqqi
http://haqqi.net

Profile
 
 
Posted: 22 January 2011 07:19 AM   [ Ignore ]   [ # 22 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  4108
Joined  11-04-2008

Datamapper’s autoloader is not compatible with any HMVC solution today.

If you’re intrested in this feature, please report this as a feature request at http://bitbucket.org/wanwizard/datamapper/issues, and add a link to this post for reference.

 Signature 

WanWizard.eu | Modular CI, an HMVC solution | DataMapper ORM

Profile
 
 
Posted: 22 January 2011 07:24 AM   [ Ignore ]   [ # 23 ]  
Summer Student
Avatar
Total Posts:  16
Joined  02-12-2010

I see “Modular CI” in your signature. Does it compatible with Datamapper ORM? It will load ORM models in other modules?

Added: I use latest HMVC here.

 Signature 

Haqqi
http://haqqi.net

Profile
 
 
Posted: 23 January 2011 06:04 AM   [ Ignore ]   [ # 24 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  4108
Joined  11-04-2008

Datamapper uses CI 2.0’s internal loader class property _ci_model_paths to determine from which paths a model can be autoloaded. In CI 1.7.x, this defaults to APPPATH only.

Support for this variable is present in both Modular CI and HMVC.

 Signature 

WanWizard.eu | Modular CI, an HMVC solution | DataMapper ORM

Profile
 
 
Posted: 23 January 2011 06:14 AM   [ Ignore ]   [ # 25 ]  
Summer Student
Avatar
Total Posts:  16
Joined  02-12-2010

Yes, i know that because from module users I can do:

$u = new User(); 

But when I try to access related field, for example “group” field (the $has_one property has been well defined), it cannot find the required class (for this example is Group class). I think it because HMVC only load module “users”, but not groups, because the URI I access is users module.

I suggest in-class solution like my post before, defining ‘module’ in $has_one or $has_many properties in class definition if possible. Or can you give other solution?

 Signature 

Haqqi
http://haqqi.net

Profile
 
 
Posted: 23 January 2011 06:27 AM   [ Ignore ]   [ # 26 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  4108
Joined  11-04-2008

That shouldn’t matter, if it needs the Group model it should autoload it, like it autoloads User.

When refering to $u->group, Datamapper __get() magic method checks the relationships, and if it determines that the property is a related model, it does a “new $class()” to autoload it.

Note that Datamapper only autoloads from modules it knows about, not from any module installed in your application! So if this Group model is in the Groups module, load the module before you can autoload it’s models! I don’t know how that works in HMVC.

 Signature 

WanWizard.eu | Modular CI, an HMVC solution | DataMapper ORM

Profile
 
 
Posted: 23 January 2011 06:51 AM   [ Ignore ]   [ # 27 ]  
Summer Student
Avatar
Total Posts:  16
Joined  02-12-2010

I think it quiet hard because from what I read, HMVC doesn’t support loading entire module. It only can load specific controller in a module. So, it can’t load module without loading the controller.

I write this in datamapper.php line 1095:

// other code before
related_properties $has_many $this->has_many[$name] $this->has_one[$name];
$module $related_properties['module']['name'];
$module_file $related_properties['module']['file'];
// this is hmvc method
Modules::load_file($module_fileAPPPATH.'modules/'.$module.'/models/');
// Instantiate it before accessing
$class $related_properties['class'];
$this->{$name} = new $class();
// other code after 

And in the user ORM, I write this.

var $has_one = array(
    
'group' => array(
      
'class' => 'group',
      
'module' => array(
        
'name' => 'groups',
        
'file' => 'group'
      
)
  )); 

It works, but i think it will give more bugs. I think your solution is better, i have to find the way to load the entire required module, or just add a line to load it.

But now somehow i think it is quiet hard to include ORM in modular programming… -_-

 Signature 

Haqqi
http://haqqi.net

Profile
 
 
Posted: 24 January 2011 03:32 AM   [ Ignore ]   [ # 28 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  4108
Joined  11-04-2008

You can always use a loader extension:

class MY_Loader extends CI_Loader
{

    
function __construct()
    
{
        parent
::__construct();
    
}

    
function add_model_path($path)
    
{
        
if ( ! in_array($path$this->_ci_model_paths) )
        
{
            $this
->_ci_model_paths[] $path;
        
}
    }

And then use

$this->load->add_model_path(APPPATH.'modules/'.$module.'/models/'); 

in your application to have Datamapper search that path as well…

 Signature 

WanWizard.eu | Modular CI, an HMVC solution | DataMapper ORM

Profile
 
 
Posted: 24 January 2011 07:11 AM   [ Ignore ]   [ # 29 ]  
Summer Student
Total Posts:  6
Joined  02-04-2010

Hello group,
I am using Datamapper for my tiny project and have a problem with the relations between to models (person and termin) with has_many AND has_one to the same model.

The Tables:

PERSON (user)
id
name

TERMIN (seminar)
id
name
dozent_id (In table foreign key for an instructor for the seminar an is a PERSON) dozent_termin

PERSONEN_TERMINE (junction table for m:m relation )
id
person_id
termin_id


with

$has_many = array(“termin”) in model “PERSON”
and
$has_many = array(“person”) in model “TERMIN”

it works well for the standard Relation - but the In table foreign Key confused me a bit.

How I relate the “dozent_id” to the model?
For example:

$u = new Person();
$u->termin->dozent->get();

This do not work. I have to put a “$have_one” relationship in the two model, but how?

Is there a way?

Sorry for my bad english.

Profile
 
 
Posted: 24 January 2011 01:36 PM   [ Ignore ]   [ # 30 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  4108
Joined  11-04-2008

@Haqqi,

A solution has been implemented in latest version on BitBucket.

This allows you to specify the path in the models advanced relationship definition, or manually (for example in the controller constructor) using the static method Datamapper::add_model_path().

 Signature 

WanWizard.eu | Modular CI, an HMVC solution | DataMapper ORM

Profile
 
 
   
3 of 53
3