ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

DataMapper ORM v1.8.2

November 30, 2011 3:43pm

Subscribe [100]
  • #571 / Jul 24, 2012 5:34am

    WanWizard

    4475 posts

    Time to do some debugging then…

  • #572 / Jul 24, 2012 6:05am

    Netstrike

    6 posts

    I have find the problem…
    I tried to instantiate the model into __construct() of library…
    Now, i Instantius the model in a method of library and it work fine.

  • #573 / Jul 24, 2012 11:19am

    WanWizard

    4475 posts

    It shouldn’t be an issue to instantiate objects in a constructor.

    Unless you model uses that library in it’s constructor. When you do that the library isn’t marked ‘loaded’ yet by CI’s singleton system, so a load in the model constructor will trigger another attempt by CI to load the library…

    If that is not the case, I can’t see why it would introduce a loop. Have you checked the backtrace to see what is calling what?

  • #574 / Jul 25, 2012 11:56am

    Andre83

    12 posts

    Hi everyone,

    a quick question about data validation using DataMapper v.1.8.2. I’ve created a model and saved some records, not setting any validation rules. I’ve then introduced a ‘required’ validation on one of the model’s fields.

    Validation works fine when trying to add new records to the database, but fails when editing previously saved data.

    E.g.

    $activity = new Activity();
    $activity->where('id', $id)->get();
     
    $activity->activity_note = '';
    $activity->save();

    In this case, being ‘activity_note’ the required field, $activity-save() should return FALSE, instead it does return TRUE.

    By the way, this is how I’ve defined the validation rule inside the Activity model:

    var $validation = array(
      'activity_note' => array(
       'label' => 'Activity note',
       'rules' => array('required')
      )
     );

    I’d be glad if you could give me any input on this, as I’m kinda stuck 😊

  • #575 / Jul 25, 2012 2:20pm

    WanWizard

    4475 posts

    Data in the database is considered correct. If you can’t take that assumption, you have a big data integrity issue 😉.
    When updating an object, it will only validate changed properties.

    So if you introduce rules afterwards that will invalidate your data, run some code that will correct your data so it’s integer again.

    Migrations are the best option for that, you don’t solve that with validation, as long as you don’t retrieve your data, it will stay incorrect in your table, and can impact code that relies on that data ( I assume you don’t put the validation rules in there for a reason).

  • #576 / Jul 25, 2012 2:25pm

    Andre83

    12 posts

    Thanks for your reply, it makes totally sense 😊

    In case one wanted to always validate data upon save, I’ve found out that we can always use something like:

    $object->force_validation()->save()

    but, as you said, data stored in the database MUST be correct in the first place.

    Thanks!

  • #577 / Jul 25, 2012 3:01pm

    Jacob F.

    15 posts

    So I’m doing an include_related followed by an or_ilike, and it seems that they cannot be used together.

    $o
     ->include_related('user',array('name'),TRUE)
     ->include_related('user/group',array('name'),TRUE)
     ->where_related('user/group','id',$id)
     ->or_ilike($col,$search) //only on subsequent queries
     ->get_paged($current_page,$display_count);

    The first query that happens (no or_ilike) has a select like this:

    SELECT `o`.*,
     `user`.`name` AS user_name,
     `user_group`.`name` AS user_group_name,
     FROM (`o`)
      LEFT OUTER JOIN ...

    But subsequent queries (triggered via AJAX) have a completely different select that seems to half ignore the include_relateds

    SELECT COUNT(*) AS `numrows`
     FROM (`o`)
      LEFT OUTER JOIN ...

    The SQL of subsequent queries after the FROM is as I expect, however, the missing pieces in the primary select that are referenced in the JOINS (which are the same in both queries) breaks because user_group_name was not defined.

  • #578 / Jul 25, 2012 4:59pm

    WanWizard

    4475 posts

    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.

  • #579 / Jul 25, 2012 6:58pm

    Jacob F.

    15 posts

    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:

    1
    1
    3
    1
    3
    2
    ...
  • #580 / Jul 26, 2012 2:35am

    WanWizard

    4475 posts

    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”...

  • #581 / Jul 26, 2012 7:30am

    Maglok

    402 posts

    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

    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

    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/advancedrelations.html

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

  • #582 / Jul 26, 2012 8:19am

    WanWizard

    4475 posts

    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

    //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")
      );
  • #583 / Jul 26, 2012 1:59pm

    Jacob F.

    15 posts

    A count() only produces a single result, so I don’t get your “271 records”...

    That’s what I had thought, until it didn’t. get_paged() produced the following SQL (I manually corrected 2 field names):

    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.

  • #584 / Jul 27, 2012 5:19am

    WanWizard

    4475 posts

    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…

  • #585 / Jul 27, 2012 1:13pm

    Jacob F.

    15 posts

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases