Welcome Guest, Not a member yet? Register   Sign In
DataMapper ORM v1.8.2

[eluser]tarciozemel[/eluser]
Relationship problem just on save

Hi, folks!

I have an relationship issue here, but the error only occurs in the save. I have an User_model and Company_model "datamappers". The relations are:

Relation table fields (I can't change the structure)
- id
- User_id
- Company_id
- Role_id
- WhateverInformation
- etc

User_model
Code:
var $has_many = array
(
    'company' => array
    (
        'class'  => 'Company_model'
        ,'other_field' => 'user'
        ,'join_other_as'=> 'Company'
        ,'join_self_as' => 'User'
        ,'join_table' => 'TB_User_Company'
    )
);

Company_model
Code:
var $has_many = array
(
    'user' => array
    (
        'class'  => 'User_model'
        ,'other_field' => 'company'
        ,'join_other_as'=> 'User'
        ,'join_self_as' => 'Company'
        ,'join_table' => 'TB_User_Company'
    )
);

I can do things like this without problems:

Code:
$user = new User_model(1);

$companies = new Company_model();
$companies->where_related('user', $user)->get_iterated();

foreach ($companies AS $c)
{
    echo $c->FantasyName . '<br />';
}

BUT, when I try to do:

Code:
$user = new User_model(1);

$company = new Company_model();
$company->FantasyName = 'Foobar Baz';

if ( ! $user->skip_validation()->save($company))
{
    echo 'OMG';
}
else
{
    echo 'SAVED';
}

I always get that error:

Quote:An Error Was Encountered

Unable to relate User_model with Company_model.

If I can get the results, why I can't save stuff?! :down:

[eluser]WanWizard[/eluser]
Can you post the "CREATE TABLE"'s for both models and the models themselfs on http://scrp.at so I have something to test with?

[eluser]tarciozemel[/eluser]
[quote author="WanWizard" date="1333400902"]Can you post the "CREATE TABLE"'s for both models and the models themselfs on http://scrp.at so I have something to test with?[/quote]

Yeah, of course! I'll send you in PM right now!

[eluser]WanWizard[/eluser]
I'll reply here as it may benefit others.

A quick scan of your code doesn't really reveal anything obvious.

What could happen: if you save an object with relations, Datamapper will first save the object itself. It will then check if related objects are passed, and if so, it will save these objects too, before creating the relation. This save with call the save() method on these objects.

In case this fails (for example because of validation rules that fail), the save and relate operation is aborted, but the return code is ignored. Which could cause your save() to return TRUE, even if related saves returned FALSE.

Can you validate if this is the case by making sure the two objects in $relations are saved (and check their status) before trying to save the object itself? If this is the issue, then you've found a bug.

[eluser]tarciozemel[/eluser]
[quote author="WanWizard" date="1333465363"]I'll reply here as it may benefit others.

A quick scan of your code doesn't really reveal anything obvious.

What could happen: if you save an object with relations, Datamapper will first save the object itself. It will then check if related objects are passed, and if so, it will save these objects too, before creating the relation. This save with call the save() method on these objects.

In case this fails (for example because of validation rules that fail), the save and relate operation is aborted, but the return code is ignored. Which could cause your save() to return TRUE, even if related saves returned FALSE.

Can you validate if this is the case by making sure the two objects in $relations are saved (and check their status) before trying to save the object itself? If this is the issue, then you've found a bug.[/quote]

So, unfortunately, it's a bug.

In the code I send you with the error, the save part is:

Code:
$relationships = array
(
    'authentication' => $this->authentication
    ,'company'       => $company
);

if ( ! $this->save($relationships))
{
    // stuff
}

When I use like this, the relation happens!

Code:
// Saved BEFORE!
$this->authentication->save();
$company->save();

$relationships = array
(
    'authentication' => $this->authentication
    ,'company'       => $company
);

if ( ! $this->save($relationships))
{
    // stuff
}

That's it. Eager to the bug fix release! :cheese:

Best regards, WanWizard!

[eluser]Davva[/eluser]
Counting related objects based on query?
I'm trying to setup a subquery in DataMapper, but I can't really understand how to get it to work.
The situation: I have two models, client and project.

A client can have many projects, a project can have only one client.

I want to list all clients by their names and next to them show the project count for each client.
For example:
Client 1 (8)
Client 2 (4)
and so on…

This I got working fine using
Code:
...
$client->include_related_count('project');
...

The code above will include the project_count for each client. Now to the problem. Each project can be either 'open' or 'closed'. This is set by an enum field named 'status' in the projects table.

So,
How can I access two separate project counters for each project? Perhaps call them 'project_count_open' and 'project_count_closed' for each client?

I have looked into subqueries, but I can't get it to work.

Suggestions greatly appreciated!

[eluser]tarciozemel[/eluser]
[quote author="Davva" date="1333474894"]Counting related objects based on query?
I'm trying to setup a subquery in DataMapper, but I can't really understand how to get it to work.
The situation: I have two models, client and project.

A client can have many projects, a project can have only one client.

I want to list all clients by their names and next to them show the project count for each client.
For example:
Client 1 (8)
Client 2 (4)
and so on…

This I got working fine using
Code:
...
$client->include_related_count('project');
...

The code above will include the project_count for each client. Now to the problem. Each project can be either 'open' or 'closed'. This is set by an enum field named 'status' in the projects table.

So,
How can I access two separate project counters for each project? Perhaps call them 'project_count_open' and 'project_count_closed' for each client?

I have looked into subqueries, but I can't get it to work.

Suggestions greatly appreciated!
[/quote]

And if you make a if...else to check what is the value of "status" in each iteration?

[eluser]Davva[/eluser]
That would work, but I was hoping there was a way to get the counts without having to iterate all objects manually. Then I'd rather just write the sql myself.

[eluser]WanWizard[/eluser]
include_related_count() is a shortcut method that generates a subquery to include the count.

If you have a more complex subquery selection, the alternative is to craft the subquery yourself. See http://datamapper.wanwizard.eu/pages/subqueries.html

[eluser]WanWizard[/eluser]
@tarciozemel,

The two objects you saved, where they new objects (not present in the database) or existing objects?

And if you do
Code:
if ( ! $this->save($company))
{
    // stuff
}
without the save() of $company first, will it be related correctly?

And which version of Datamapper do you use? The latest from bitbucket or one of the distributions?




Theme © iAndrew 2016 - Forum software by © MyBB