Welcome Guest, Not a member yet? Register   Sign In
In-Table Foreign Keys in DataMapper ORM
#1

[eluser]tarciozemel[/eluser]
Hi!

I'm trying to test some features of the DataMapper ORM library (http://datamapper.wanwizard.eu/).

So, in this page of the documentation (http://datamapper.wanwizard.eu/pages/adv...tions.html) I see the In-Table Foreign Keys feature - personaly, I don't like the default third normal form (http://en.wikipedia.org/wiki/Third_normal_form) of the library.

But, unfortunately, I was can't implemented the In-Table Foreign Keys... For some reason, the DataMapper still looking for a join table, even if I already created a foreing key in my table.

So, someone, please, could show me some examples about how implement the In-Table Foreign Keys in DataMapper ORM?!

Great regards!
#2

[eluser]WanWizard[/eluser]
Datamapper has built-in support for ITFK's for one-to-one and one-to-many relations, it will detect and use them automatically.

Now, you're stating you're using an advanced relationship definition, which means you overrule the automatic detection because you define everything by hand.
Which is where the problem must be, but since you don't give us your schema (of the tables involved), nor the model definition, all I can do is guess.
#3

[eluser]tarciozemel[/eluser]
Yeah, it's true. My fault not put the schema. Fortunately, consulting the documentation more deeper, a find the solution: the "join_other_as" and "join_self_as" atributes.

I use table names unlike the indicated in docs, so it's necessary use this atributes on definition of the relatioship variables. For example:
Code:
var $has_one = array(
    'CLASS' => array(
        'join_other_as' => 'RELATIONSHIP_TABLE_NAME',
        'join_self_as' => 'SELF_TABLE_NAME'
    )
);

For more information, see that page of the documentation: http://datamapper.wanwizard.eu/pages/adv...tions.html

Thank you!
#4

[eluser]WanWizard[/eluser]
As you can see on that same page, 'join_self_as' indicates the column name to be used as key. This column name MUST be ending with '_id', which you should not specify (specify 'user' if the column is called 'user_id'). Same for 'join_other_as'. They are not table names!

You build relationship between models, the table name used for the model is defined in the model, not in the relationship. The only table name there is 'join_table', which is used in a many-to-many relationship with a non-standard table name.

Also, do not forget to define both ends of the relationship, in exactly the same way. Depending on the type of query Datamapper uses the parent or the child definition to construct the query.
#5

[eluser]tarciozemel[/eluser]
OK, so I not understood very well... Let's some example. I want a 1:N relationship according this:

user_model.php
Code:
var $has_one = array(
    'user_group' => array(
        'class' => 'user_group_model'
    )
);


user_group_model.php
Code:
// In the "group" table, I have only the "id", "name" and "desc" colums
var $has_many = array(
    'user' => array(
        'class' => 'user_model'
        'join_self_as' => 'group' // In the "user" table, exists a "group_id" colum
    )
);

When I try do this:

Code:
$user = new User_model();
$user->where('login', 'foobar')->get();
$user->user_group->get();
echo $user->user_group->desc;

I give this error:

Quote:DataMapper Error: 'User_model' is not a valid parent relationship for User_group_model. Are your relationships configured correctly?

So, where's my mistake? I have to specify a "join_self_as" in the user_model even the other table not having a relationship field? If yes, how?

Regards!
#6

[eluser]WanWizard[/eluser]
From your code snippets I can't see how you named your classes.

They should be called User_model and User_group_model, but in your code you are using 'user_group', which is conflicting.

Instead of trying to use all kinds of non-standard naming, why not just follow the standards and get rid of these issues?
#7

[eluser]tarciozemel[/eluser]
Thank you for your reply!

The problem is: the DB people already sent me the entire database, now I have no choice... Besides, the DB not uses a third table in 1:N relationships. Thats it. =/

In my example, I use "user_group" because I followed the Attributes Table instructions (and yes, my classes ares "User_model" and "User_group_model").

Code:
var $has_one = array(
    '>>>user_group<<<' => array(
        'class' => 'user_group_model'
    )
);

The "class" isn't for that? I'm a little confused...

Regards!
#8

[eluser]WanWizard[/eluser]
Relations are made on model name, not on class name.

The model name is set automatically on a relation, and is based on the class name. If you want to override it, use the 'other_field' parameter of the advanced relation definition.

See http://datamapper.wanwizard.eu/pages/adv...tions.html
#9

[eluser]tarciozemel[/eluser]
With the help of my pal, I did this works! I had to use “join_self_as” in user model even that not have an FK in the other table. So, the solution is:

user_model.php (class User_model)
Code:
var $has_one = array(
    'user_group' => array(
        'class' => 'user_group_model',
        'other_field' => 'user',
        'join_other_as' => 'group',
        'join_self_as' => 'user'
    )
);


user_group_model.php (class User_group_model)
Code:
var $has_many = array(
    'user' => array(
        'class' => 'user_model',
        'other_field' => 'user_group',
        'join_other_as' => 'user',
        'join_self_as' => 'group'
    )
);

I think DataMapper documentation should have more examples, especially in the "Advanced Relationships" section. This would greatly will help people! :-D

Very thank you for you help and congratulations for the DataMapper!




Theme © iAndrew 2016 - Forum software by © MyBB