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

[eluser]WanWizard[/eluser]
I sincerely doubt that that query will produce a count query under any circumstance. So something else must be wrong.

That bears the signature of a $o->count() query, which by the way IS run by get_paged() to get the total number of records.This query is run on a clone of the current object.

This means that if you have configured the database (db_params in the datamapper config) so that all objects will use the same $this->db instance, the query on the clone will destroy the pending query.

So check your config, db_params may NOT be set to FALSE.

[eluser]Jacob F.[/eluser]
Hi WanWizard,

I checked the datamapper config, and originally it was $config['db_params']='' so I tried $config['db_params']=FALSE and $config['db_params']=TRUE and it broke for both.

Since get_paged() produces 2 queries (the first being the COUNT), it seems it's failing on the first query (and it doesn't get to the second where it retrieves the actual records). I can't even think of how to get that count in SQL without the following happening:

I manually merging the outputted queries (the 1st, COUNT, and the 2nd, regular select) to at least avoid an error, and it gave me counts of each record--so if the JOINs produced 3 records, I got 271 records with values of the counts:
Code:
1
1
3
1
3
2
...

[eluser]WanWizard[/eluser]
What get_paged() does is clone the object, including it's $this->db instance. It then strips the select and the order_by clauses and adds a count(*), and runs that to count the records in the result.

Based on that count, and on the parameters you pass to get_paged(), it will add a limit and offset to the original query and runs that. The code doesn't have any way to skip the second query.

A count() only produces a single result, so I don't get your "271 records"...

[eluser]Maglok[/eluser]
Still loving the library! Keep up the good work and awesome replies.

Here is my latest.

Imagine if you will a Party and a User datamapper class.

This is some of the party.php
Code:
var $has_one = array(
   "leader" => array(
    "class" => "user",
    "other_field" => "leader")
   );

var $has_many = array(
   "user" => array(
     "join_self_as" => "party",
     "join_other_as" => "user",
     "join_table" => "ccj_pa_party_user")
   );

This is some of the user.php
Code:
var $has_many = array(
   'leader' => array(
    'class' => 'party',
    'other_field' => 'leader'),
   'party' => array(
    'join_self_as' => "user",
    "join_other_as" => "party",
    "join_table" => "ccj_pa_party_user")
  );

The has_one leader works perfectly. The database has a leader_id and datamapper grabs it and I can reference to a User object called leader with $party->leader.

However when I try to apply that knowledge to the has_many I get problems. As I wrote it down this is how it works. I would love to be able to tweak the reference though. I would like $party->players instead of $party->user. Whichever way I try I keep getting errors.

I used this page as a guide: http://datamapper.wanwizard.eu/pages/adv...tions.html

I tried using the 'class' option and changing the reference names around.

[eluser]WanWizard[/eluser]
Here's a post that describes the advanced relationship definition in more detail: http://ellislab.com/forums/viewthread/216316/#999408

so you need something like
Code:
//party model
var $has_many = array(
   "player" => array(
     "class" => "user",
     "other_field" => "party",
     "join_self_as" => "party",
     "join_other_as" => "user",
     "join_table" => "ccj_pa_party_user")
   );

// user model
var $has_many = array(
   'party' => array(
    "other_field" => "user",
    'join_self_as" => "user",
    "join_other_as" => "party",
    "join_table" => "ccj_pa_party_user")
  );

[eluser]Jacob F.[/eluser]
[quote author="WanWizard" date="1343284535"]A count() only produces a single result, so I don't get your "271 records"...[/quote]

That's what I had thought, until it didn't. get_paged() produced the following SQL (I manually corrected 2 field names):
Code:
SELECT COUNT(*) AS `numrows`
FROM (`order`)
  LEFT OUTER JOIN `user` user ON `user`.`id` = `order`.`user_id`
  LEFT OUTER JOIN `group_user` user_group_user ON `user`.`id` = `user_group_user`.`user_id`
  LEFT OUTER JOIN `group` user_group ON `user_group`.`id` = `user_group_user`.`group_id`
  WHERE UPPER(`order`.`order_number`) LIKE '%$searchTerm%'
   OR UPPER(`order`.`job_number`) LIKE '%$searchTerm%'
   #OR UPPER(`user_group_name`) LIKE '%$searchTerm%' //from get_paged() - wrong
   OR UPPER(`user_group`.`name`) LIKE '%$searchTerm%' //corrected
   #OR UPPER(`user_name`) LIKE '%$searchTerm%' //from get_paged() - wrong
   OR UPPER(`user`.`name`) LIKE '%$searchTerm%' //corrected
   OR UPPER(`order`.`date`) LIKE '%$searchTerm%'
   OR UPPER(`order`.`id`) LIKE '%$searchTerm%'
   OR UPPER(`order`.`complete`) LIKE '%$searchTerm%'
  GROUP BY `order`.`id`;

The above retrieves 271 rows, and the values appear the be counts of their occurrence due to the LEFT OUTER JOIN (I believe in this case, it should be a RIGHT OUTER JOIN).

I think the GROUP_BY in the COUNT query is the cause of the multiple records being retrieved instead of just a count. However, without the GROUP_BY, the second query retrieves multiple records for one order if a user is a member of multiple groups. Would it be better to use a DISTINCT--like SELECT COUNT(DISTINCT `order`.`id`) ?

The bigger problem is the incorrect field-names in 2 of the OR clauses: they're correctly referenced in the 2nd query but not in the 1st (the COUNT). I'm not sure how to handle this because I pass into a function the partially-created DataMapper object (get_paged() is run inside the fn) and an array of field names as they will be aliased by DataMapper: user_group_name which references `user_group`.`name`. Supplying user_group_name works for the query that retrieves records, but does not for the COUNT query--supplying `user_group`.`name` works for the COUNT query but not the record-retrieving query.

[eluser]WanWizard[/eluser]
That is indeed because of the GROUP BY clause. And probably not so easy to fix.

Can you add an issue for this: http://bitbucket.org/wanwizard/datamapper/issues, and add a link to your post here?

And for reference, include the exact code that produces that query, without it reproducing it will be difficult...

[eluser]Jacob F.[/eluser]
Done: https://bitbucket.org/wanwizard/datamapper/issue/74/

Thanks!

[eluser]Jacob F.[/eluser]
Hi again,

I'm trying to set up a custom validation function _unique_not_deleted($field) that is similar on unique() whereby it checks to see if $field is not unique and then checks to see if $field is not deleted (TRUE if neither):

Code:
function _uniqueNotDeleted($field) {
if ( ! $this->{$field}->unique() ) {
  return ( ! $this->deleted )? TRUE : FALSE;
} else return TRUE;//fi $this->{$field}->unique()
}//_uniqueNotDeleted()

But I get the error
Quote:Call to a member function unique() on a non-object

which makes me think that I will have to re-create the unique() function within my custom one; but when reading the validation documentation (Max Size (pre-processing example)) it seems like I should be able to use pre-defined functions on $this->{$field} without having to first run a ->get().

P.S. I also tried $this->{$field}->unique($field) (same error) and $this->unique($field) (Exception: Unable to call the method "unique").


[b]I realised I would need to re-create the unique() function because I actually need to check return ( ! $row->deleted )? TRUE : FALSE ;

[eluser]WanWizard[/eluser]
Datamapper doesn't have a method called 'unique'. And $this->{$field} is not an object, it's a column value, so the error you get is quite logical.

The internal validation rule is processed by the method "_unique", which you call using $this->_unique($this->{$field}).

Note that this is an internal Datamapper method, which may not work anymore in future versions.




Theme © iAndrew 2016 - Forum software by © MyBB