EllisLab text mark
Advanced Search
50 of 66
50
   
DataMapper ORM v1.8.2
Posted: 25 September 2012 08:40 AM   [ # 741 ]   [ Rating: 0 ]
Avatar
Joined: 2008-11-04
4489 posts

A quick look in the code reveals that you can either pass an object (in which $this->model is used to find the relation), or a string (which should be the relation name).

In the first case you have the requirement that the relation must have the same name as the class, in the second you can’t set a filter on a specific object.

Perhaps you can work around it using

$user = new User(1);
$item = new Item();
$item->where_join_field('orders''status''active')->where('user_id'$user->id)->get(); // you might have to prefix "user_id" 
 Signature 

Me: WanWizard.eu | My company: Exite | Datamapper: DataMapper ORM <= LOOKING FOR A NEW MAINTAINER!

 
Posted: 25 September 2012 09:55 AM   [ # 742 ]   [ Rating: 0 ]
Joined: 2012-01-24
23 posts

@WanWizard,

I just made the relationship key name identically same between User and Item (the relation name is ‘orders’ in $has_many variables of User and Item model).
And then I tried to run the code but it outputs an error :

Unknown column 'mc_orders.status' in 'where clause'

SELECT FROM (`mc_item`) WHERE `mc_orders`.`status` = 'active' AND `user_id` = 

It is weird that the query doesn’t include table mc_orders using this code.
What am I doing wrong here?

 
Posted: 25 September 2012 11:44 AM   [ # 743 ]   [ Rating: 0 ]
Avatar
Joined: 2008-11-04
4489 posts

If you do

$parent->where_join_field()->... 

there is no technical need to include the child table in the query. That would mean an extra join, a slower query, and more CPU and memory usage. So Datamapper doesn’t include it.

If you do need the child, use

$parent->child->where_join_field()->... 

In your example I assumed that ‘status’ was a column in your join table. If it isn’t, you should not be using where_join_field(), but just where().

 Signature 

Me: WanWizard.eu | My company: Exite | Datamapper: DataMapper ORM <= LOOKING FOR A NEW MAINTAINER!

 
Posted: 25 September 2012 01:28 PM   [ # 744 ]   [ Rating: 0 ]
Joined: 2012-01-24
23 posts

@WanWizard,
Sorry, I think I find myself not clear enough about the usage of where_join_field()
If

$parent->where_join_field()->... 

does not include the join-table, then how does the query recognize the join-field name?

If I take a look back on the documentation http://datamapper.wanwizard.eu/pages/getadvanced.html#_join_field
I’m sure I’m quite understand with this query

$user->alarm->where_join_field($user'wasfired'FALSE)->get(); 

However, I think it only works if model user has_many alarm, and model alarm has_many user, with join-table user_alarm. I mean, both models have basic and minimum many-to-many relationship setup.

But in my case, where I change the has_many relationship to ‘orders’, the where_join_field() seems doesn’t want to work, even though I’m definitely sure that I follow exactly the example code.

As for the field ‘status’, you are correct, the field ‘status’ is in my join-table, and I want to filter the main table based on it.

Really appreciate your help to solve this issue.
Thanks

 

 
Posted: 25 September 2012 02:04 PM   [ # 745 ]   [ Rating: 0 ]
Joined: 2010-10-27
114 posts

Not used datamapper in a while set everything up as you should (I think!) Trying to do a simple get but getting the following error:

Cannot access empty property in…...datamapper.php on line 2370

Is there a simple cause for this?

 
Posted: 25 September 2012 05:29 PM   [ # 746 ]   [ Rating: 0 ]
Avatar
Joined: 2008-11-04
4489 posts

@rick20,

What I mean is the following:

Say you have the tables “parents” -> ‘children_parents” -> “children”. Two tables in a many-to-many relation, and a join table relating the two. Say you have a column in the join table called “field”.

$parent->where_join_field('child''field''value')->get(); 

will select all parent records which have a join table record in which the column ‘field’ has the value ‘value’. Note that for this query, the ‘child’ table doesn’t need to be joined.

So, if you do

$parent->where_join_field('child''child.field''value')->get(); 

you would get your error, since there’s no table in the query called ‘child’.

The first parameter of *_related() is the relation name the query is on (and not the model or table on the other side).

 Signature 

Me: WanWizard.eu | My company: Exite | Datamapper: DataMapper ORM <= LOOKING FOR A NEW MAINTAINER!

 
Posted: 25 September 2012 05:33 PM   [ # 747 ]   [ Rating: 0 ]
Avatar
Joined: 2008-11-04
4489 posts

@Andy78,

For starters, get the latest version from Bitbucket. Line 2370 is an empty line in my version, so I haven’t got a clue what causes that message.

You get his error if you would do

$this->$var->method(); 

and $var is not defined or null. This syntax isn’t used in Datamapper.

I assume this will also give that error:

$value $this->{$var}

and $var is not defined or null. This is used all over the place.

 Signature 

Me: WanWizard.eu | My company: Exite | Datamapper: DataMapper ORM <= LOOKING FOR A NEW MAINTAINER!

 
Posted: 25 September 2012 09:40 PM   [ # 748 ]   [ Rating: 0 ]
Joined: 2012-01-24
23 posts

@WanWizard,

I just tried using where_related() but it’s actually did LEFT OUTER JOIN with join-table and the child table.
And, the where_related() seems to me always look for ‘field’ in child table, instead in join-table.

So, from here I think I cannot use where_related().

Actually If I see from the SQL error, when using where_join_field(), I just only need to tell datamapper to use join-table alias name in WHERE condition, instead of the join-table name itself.

Because I see that the LEFT OUTER JOIN already make an alias for the join-table, but the WHERE still access the join-table name. And this outputs the error ‘Unknown column ... in WHERE clause’

Any way to do this thing?

Please kindly help.

 
Posted: 26 September 2012 01:38 AM   [ # 749 ]   [ Rating: 0 ]
Avatar
Joined: 2008-11-04
4489 posts

Sorry, my bad.

I should have written ‘where_join_field’ in that example. I’ll change it. ‘where_related’ indeed always operates on the related table.

And it’s correct that Datamapper aliases all tables, so when referring to a column in another table you should use the alias, not the table name.

I’m still trying to figure out what you’re doing. Can you post the exact query you run, and the output of check_last_query()?

 Signature 

Me: WanWizard.eu | My company: Exite | Datamapper: DataMapper ORM <= LOOKING FOR A NEW MAINTAINER!

 
Posted: 26 September 2012 03:24 AM   [ # 750 ]   [ Rating: 0 ]
Joined: 2012-01-24
23 posts

@WanWizard,

Below is my sample codes

class Model_User extends DataMapper {

  
public $table 'users';

  public 
$has_many = array(
    
'orders' => array(
      
'class' => 'model_item',
      
'other_field' => 'orders',
      
'join_table' => 'orders',
      
'join_self_as' => 'user',
      
'join_other_as' => 'item'
    
),
    
'favorites' => array(
      
'class' => 'model_item',
      
'other_field' => 'favorites',
      
'join_table' => 'favorites',
      
'join_self_as' => 'user',
      
'join_other_as' => 'item'
    
)
  );
  
  function 
__construct($id NULL)
  
{
    parent
::__construct($id);
  
}
class Model_Item extends DataMapper {
 
  
public $table 'items';
  
  public 
$has_many = array(
    
'orders' => array(
      
'class' => 'model_user',
      
'other_field' => 'orders',
      
'join_table' => 'orders',
      
'join_self_as' => 'item',
      
'join_other_as' => 'user'
    
),
    
'favorites' => array(
      
'class' => 'model_user',
      
'other_field' => 'favorites',
      
'join_table' => 'favorites',
      
'join_self_as' => 'item',
      
'join_other_as' => 'user'
    
)
 );
  
  function 
__construct($id NULL)
  
{
    parent
::__construct($id);
  
}

And here are my tables:

CREATE TABLE IF NOT EXISTS `mc_users` (
  `
idint(11NOT NULL AUTO_INCREMENT,
  `
usernamevarchar(100NOT NULL,
  `
passwordvarchar(100NOT NULL,
  `
createddatetime NOT NULL,
  `
statusint(11NOT NULL,
  
PRIMARY KEY (`id`)
);

CREATE TABLE IF NOT EXISTS `mc_items` (
  `
idint(11NOT NULL AUTO_INCREMENT,
  `
namevarchar(100NOT NULL,
  `
createddatetime NOT NULL,
  `
statusint(11NOT NULL,
  
PRIMARY KEY (`id`)
);

CREATE TABLE IF NOT EXISTS `mc_orders` (
  `
idint(11NOT NULL AUTO_INCREMENT,
  `
user_idint(11NOT NULL,
  `
item_idint(11NOT NULL,
  `
statusint(11NOT NULL,
  
PRIMARY KEY (`id`)
);

CREATE TABLE IF NOT EXISTS `mc_favorites` (
  `
idint(11NOT NULL AUTO_INCREMENT,
  `
user_idint(11NOT NULL,
  `
item_idint(11NOT NULL,
  
PRIMARY KEY (`id`)

This is the code in my controller:

$this->output->enable_profiler(TRUE);
    
$user = new Model_User(1);
$user->orders->where_join_field('orders''status'1)->get(); 

With this line of code, I got the following error:

Unknown column 'mc_orders.status' in 'where clause'

SELECT `mc_items`.* FROM (`mc_items`) LEFT OUTER JOIN `mc_ordersorders_orders ON `mc_items`.`id` = `orders_orders`.`item_idWHERE ( `mc_orders`.`status` = ) AND `orders_orders`.`user_id` = 

I’ve tried any combination of codes using where_join_field, include_join_field, where_related, and a lot more I can think of, but still no luck.

Really need your help here, thanks.

 
Posted: 26 September 2012 08:44 AM   [ # 751 ]   [ Rating: 0 ]
Avatar
Joined: 2008-11-04
4489 posts

Thanks.

I have to find time to recreate this to see what goes wrong. I might have to do with the fact that you use advanced relationship definitions, it seems detection of the table alias goes wrong…

 Signature 

Me: WanWizard.eu | My company: Exite | Datamapper: DataMapper ORM <= LOOKING FOR A NEW MAINTAINER!

 
Posted: 26 September 2012 10:27 AM   [ # 752 ]   [ Rating: 0 ]
Joined: 2012-07-05
11 posts

I’m trying to do something like this:

// ...
$model->where_related('relative1/relative2', array('field1' => 'val1''field2' => 'val2'))->get(); 

But it doesn’t appear to support having an array for fields instead of a field and value string, as I get a db error with Array as the field name.

Is there a way to perform an advanced get with more than one field and if not, what would be a good alternative?

Thanks,
Matt

 
Posted: 26 September 2012 11:31 AM   [ # 753 ]   [ Rating: 0 ]
Joined: 2012-01-24
23 posts

@maikens AFAIK the where_related() only accept string for field parameter.
You can find more explanation about where() and its variations from the documentation http://datamapper.wanwizard.eu/pages/getadvanced.html

But in your case, maybe you can use the following:

$model
  
->where_related('relative1/relative2''field1''val1'
  ->
where_related('relative1/relative2''field2''val2')
  ->
get(); 

Hope this helps

 
Posted: 26 September 2012 11:37 AM   [ # 754 ]   [ Rating: 0 ]
Joined: 2012-01-24
23 posts

@WanWizard Thanks so much smile
I really do wish datamapper keeps better and better everytime.
So far, this is the easiest but powerful ORM for codeigniter I can find from google.

Really appreciate your help smile

 
Posted: 26 September 2012 11:56 AM   [ # 755 ]   [ Rating: 0 ]
Joined: 2012-07-05
11 posts

@rick20 thanks. I ended up doing it like this:

$model->related1->get();
$model->related1->related2->where(array(('field1' => 'val1''field2' => 'val2'))->get() 

Your way seems a bit cleaner, but meh.

thanks again for the help.

 
50 of 66
50