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.

Gas ORM 2

March 16, 2012 11:36pm

Subscribe [39]
  • #61 / Mar 31, 2012 3:36pm

    toopay

    1583 posts

    @Khrome83, in the past there was already a request to include related entities within write operation, but atm i still think Gas ORM design already provide several hooks point, which make that request not emerged as a necessary requirement.

    But this week, i’ve just completely put relationship insertion using this new method instead in my hooks/callback, within my company application, and i feel that really helpful 😊 Callbacks now can be used for other things which more custom/specific than that.

    Would it make sense to have entities.user.parent and/or a option to find. Is .parent even needed in general, or does child work both ways depending on where your inserting from?

    yes it does. Just to make it clear how this related->set works, lets throw all typical gas relationships :

    // One-to-one
    'wife'   => ORM::has_one('\\Model\\Wife'),                       // Model\Wife is the child
    'father' => ORM::belongs_to('\\Model\\Father'),                  // Model\Father is the child
    
    // One-to-many
    'kid'    => ORM::has_many('\\Model\\Kid'),                       // Model\Kid is the child
    
    // many-to-many
    'job'    => ORM::has_many('\\Model\\Job\\User => \\Model\\Job'), // Model\Job\User is the pivot and Model\Job is the child

    Then, regarding your schema :

    Profiles
    Belongs To - Users (or would Has One be Better)

    Do you really need profiles being different entity from user entity? I think except you are in a very specific (rare) case, profile will be better as a part of user entity itself.

    Articles
    Belongs To - Users (or would Has One be Better)
    ...
    Comments -
    Belongs To - Articles
    Belongs To - User (or would Has One be Better)

    If you define one-to-many from user entity, than belongs-to already correct. belongs_to is different from has_one. Belongs to, implicitly tell that every record is bound to one parent record in foreign table. In has_one table, some record can have no child record.

    So with finder, when I do All, would this cause any problems. For example if I want to get all Articles by a User as well as the comments and the comments users names...
    ...
    I would not end up with something like this to get the comments user name. (not actual code)

    User()->Articles->Comments->User()->Name

    I dont think there will be any issues about that. As long you define your entities relationship correctly, you should be fine 😊

  • #62 / Mar 31, 2012 5:44pm

    Khrome83

    22 posts

    I am starting to get into more complex queries and am trying to figure out the best way to handle this.

    I have a table of all the “featured” content on the side, and the start and end date for the promotions.

    Basically I want to retrieve all “featured” content from the DB as long as the current date is after the start and before the end date.

    I can think of three posibilities, but with the exception of one I don’t know the correct way to handle them.

    1. Is there a way with GAS 2.0 to specificity this complex select and put the load in the DB?
    2. I use the model to control what data is received (modifying data in a _get callback?)?
    3. I do the test inside the controller where I am accessing the data and only send the acceptable data to the view?

    Want to make sure I go in the better direction.

    Thanks

  • #63 / Apr 01, 2012 9:15am

    toopay

    1583 posts

    Basically I want to retrieve all “featured” content from the DB as long as the current date is after the start and before the end date.

    Gas ORM mostly support CI query builder syntax and methods. Thats to say, you can use something like :

    $feature = Model\Feature::select('name')->where("date > $start and date < $end")->all();
  • #64 / Apr 01, 2012 3:54pm

    mecharius

    21 posts

    Hi toopay, I upgraded to 2.1 and those changes are cool. 

    Now however when I call save() I’m getting a series of errors from classes/core.php line 2475 related to $db[‘default’][‘pdodriver’] not being defined in config/database.php.

    A PHP Error was encountered
    
    Severity: Notice
    
    Message: Undefined property: CI_DB_mysql_driver::$pdodriver
    
    Filename: classes/core.php
    
    Line Number: 2475
    
    Backtrace:
    
    File: C:\Web\apache2\htdocs\grades\application\third_party\gas\classes\core.php
    Line: 2475
    Function: _exception_handler
    
    File: C:\Web\apache2\htdocs\grades\application\third_party\gas\classes\core.php
    Line: 645
    Function: __callStatic
    
    File: C:\Web\apache2\htdocs\grades\application\third_party\gas\classes\core.php
    Line: 645
    Function: insert_id
    
    File: C:\Web\apache2\htdocs\grades\application\third_party\gas\classes\core.php
    Line: 910
    Function: call_user_func_array
    
    File: C:\Web\apache2\htdocs\grades\application\third_party\gas\classes\orm.php
    Line: 818
    Function: compile
    
    File: C:\Web\apache2\htdocs\grades\application\controllers\profile.php
    Line: 57
    Function: __call
    
    File: C:\Web\apache2\htdocs\grades\application\controllers\profile.php
    Line: 57
    Function: save
    
    File: C:\Web\apache2\htdocs\grades\index.php
    Line: 287
    Function: require_once

    The insert or update still works…

    One work around is by editing config/database.php file and adding

    $db['default']['pdodriver'] = NULL;

    But I’ve also submitted a pull request on github where I’ve added an isset() check.

  • #65 / Apr 02, 2012 2:02am

    indCI

    11 posts

    Thanks for addressing the issue of return type.
    And yes, I was still in 2.0.0, I didn’t realize they were for 2.1.0 😊

    Since version 1.X.X, relationship method always works this way :
    has_one => returning an object
    belongs_to => returning an object
    has_many => returning an array of object

    For some reason I’m getting an array from a model that has one-to-one relationship.
    I’m calling $user->userdata() and it returns an array with single object. The user model has this line in self::$relationships

    'userdata' => ORM::has_one('\\Model\\Userdata')

    and userdata has

    'user' => ORM::belongs_to('\\Model\\User')

    and result is

    array(1) {
      [0]=>
      object(Model\Userdata)#93 (14) {
     
        ...
     
      }
    }

    Am I doing something wrong here?

  • #66 / Apr 02, 2012 5:13am

    toopay

    1583 posts

    One work around is by editing config/database.php file and adding

    $db['default']['pdodriver'] = NULL;

    @mecharius Gas ORM repo is always syncing with EllisLab repo (since it use EllisLab repo as git submodule), and those line you’ve pointed is because the new database.php in CI version 3.0 looks like this and pdodriver is available on DB driver params. Anyway, thanks for the pull.

  • #67 / Apr 02, 2012 5:31am

    toopay

    1583 posts

    For some reason I’m getting an array from a model that has one-to-one relationship.
    I’m calling $user->userdata() and it returns an array with single object. The user model has this line in self::$relationships

    'userdata' => ORM::has_one('\\Model\\Userdata')

    and userdata has

    'user' => ORM::belongs_to('\\Model\\User')

    and result is

    array(1) {
      [0]=>
      object(Model\Userdata)#93 (14) {
     
        ...
     
      }
    }

    Am I doing something wrong here?

    @IndCI, look at this Unit testing file at line 96 and 105. It verify that has_one and belongs_to relationship were correctly returning a typicall Gas object. Are you sure you already upgrade your version ? 😊

  • #68 / Apr 02, 2012 7:18am

    indCI

    11 posts

    Are you sure you already upgrade your version ? 😊

    Not yet, but I thought it was that way since 1.X.X?
    Anyway, it’s not a big deal, thanks for the help.

  • #69 / Apr 02, 2012 8:32am

    toopay

    1583 posts

    Are you sure you already upgrade your version ? 😊

    Not yet, but I thought it was that way since 1.X.X?
    Anyway, it’s not a big deal, thanks for the help.

    It is. The new unit test file i add, is to clarify that. And its a big deal, since its explicitely represent the relationship type. Let me know if you still have this issue or you already resolve that.

  • #70 / Apr 02, 2012 9:47am

    mecharius

    21 posts

    Hi Toopay,
    Yet another example of me being a little bit thick probably ... but I’m getting some errors which a “git bisect” tracks down to when I updated to Gas 2.1.0.

    When I call:

    $coursework = Model\Coursework::find($id)
    $coursework->title = $this->input->post('title');
    ...
    $coursework->save();

    I get

    An Error Was Encountered
    
    Cannot determine the entity models for coursework.0

    This seems to be related to line 660 of classes/core.php, because the key($entity) is 0. (Confirmed by doing a var_dump).

    $key = key($entity);
    $values = current($entity);
    $model = $gas->meta->get('entities.'.$related.'.'.$key, NULL);
    
    if (empty($model)) 
    {
     throw new \InvalidArgumentException('Cannot determine the entity models for '.$related.'.'.$key);
    }

    Looking back through the code I can’t quite work out where these array indices are being set. Any thoughts on how this might come about?  When I add var_dump($entity) at line 660 of core.php I get

    array(2) {
      [0]=>
      object(Model\Coursework)#62 (14) {
        ["primary_key"]=>
        string(2) "id"
    ...

    Should this array have two elements?

  • #71 / Apr 02, 2012 9:54am

    toopay

    1583 posts

    @mecharius, could you post the full code you used?

  • #72 / Apr 02, 2012 10:06am

    mecharius

    21 posts

    The model looks like the following: (Github)

    <?php namespace Model;
    
    /* This basic model has been auto-generated by the Gas ORM */
    
    use \Gas\Core;
    use \Gas\ORM;
    
    class Coursework extends ORM {
    
     public $primary_key = 'id';
    
     function _init()
     {
    
      self::$relationships = array (
       'subject'   =>   ORM::belongs_to('\\Model\\Subject'),
       'user'   =>  ORM::belongs_to('\\Model\\User'),
       'status'  =>  ORM::belongs_to('\\Model\\Status'),
      );  
    
      self::$fields = array(
       'id'    =>   ORM::field('auto[10]'),
       'users_id'   =>   ORM::field('int[10]'),
       'subject_id'  =>   ORM::field('int[10]'),
       'title'   =>   ORM::field('char[255]'),
       'due_date'  =>  ORM::field('date'),
       'status_id'  =>   ORM::field('int[10]'),
       'notes'   =>   ORM::field('string'),
       'score'   =>   ORM::field('int[3]'),
       'weighting'  =>   ORM::field('int[3]'),
       'deleted'   =>   ORM::field('numeric[1]'),
       'created_on'  =>   ORM::field('datetime'),
       'modified_on'  =>   ORM::field('datetime'),
      );
    
      $this->ts_fields = array('modified_on','[created_on]');
    
     }
    }


    The controller looks like this (Github)

    /*
       * Edit a coursework
       */
      public function edit ($id = 0)
      {
       // check we have find a coursework for this id
       $coursework = Model\Coursework::find($id);
       if ($coursework == NULL) {
        $this->session->set_flashdata('error','Error finding coursework - are you sure that coursework exists?');
        redirect('dashboard');
       }
    
       // check this user is allowed to access it
       if ($this->usr->id != $coursework->users_id) 
       {
        $this->session->set_flashdata('error','You do not have permission to edit this coursework');
        redirect('dashboard');
       }
    
       // set and run validation rules
       $this->form_validation->set_rules($this->validation_rules);
    
       // check if we submitted our edits and they are valid
       if($_POST && $this->form_validation->run() === TRUE)
       {
        // update the model
        $coursework->title = $this->input->post('title');
        $coursework->due_date = $this->input->post('due_date');
        $coursework->status_id = $this->input->post('status_id');
        $coursework->notes = $this->input->post('notes');
        $coursework->score = $this->input->post('score');
        $coursework->weighting = $this->input->post('weighting');
    
        // save the model
        if ($coursework->save())  //// **** ERROR HERE
        {
         $this->recalculate_weightings($coursework->subject_id);
         $this->session->set_flashdata('success','Successfully updated coursework');
         redirect('coursework/view/'.$coursework->id);
        }
        else
        {
         $this->session->set_flashdata('error','Error saving coursework, please try again');
        }
       }
    
       // get the list of statuses we can have
       $data['status_list'] = Model\Status::all();
    
       // show the editing form
       $data['coursework'] = $coursework;
       $data['action'] = 'edit';
       $data['content'] = $this->load->view('coursework/manage_single', $data, true);
       $this->load->view('template',$data);
      }

    Thanks for having a look :D

  • #73 / Apr 02, 2012 10:12am

    mecharius

    21 posts

    Hmm… on looking at the core.php file a bit more could it be that relations are not being added properly for cascading updates?  (I can squash this issue by modifying save() in core.php to not do any cascaded updates.)

    Not sure why this would only happen with this model though and not others which are quite similar.

  • #74 / Apr 02, 2012 10:40am

    toopay

    1583 posts

    @mecharius, well thats weird. The cascading update only triggered when you set some entity within related container data, as shown at core.php line 650. Ok, lets try debug it lil bit. Could you modify your controller above, at this part :

    die('<pre>'.var_export($coursework, TRUE).'</pre><p>‘);<br />
    // save the model<br />
    if ($coursework->save())  //// **** ERROR HERE
    </pre>
    and share the dump result.

  • #75 / Apr 02, 2012 10:44am

    mecharius

    21 posts

    For some reason I quite enjoy typing die() into PHP sometimes :D

    Model\Coursework::__set_state(array(
       'primary_key' => 'id',
       'namespace' => 'Model',
       'table' => 'coursework',
       'composite_key' => 
      array (
      ),
       'foreign_key' => 
      array (
      ),
       'empty' => false,
       'errors' => 
      array (
      ),
       'extension' => NULL,
       'recorder' => 
      Gas\Data::__set_state(array(
         'collections' => 
        array (
        ),
      )),
       'record' => 
      Gas\Data::__set_state(array(
         'collections' => 
        array (
          'data' => 
          array (
            'id' => '52',
            'users_id' => '1',
            'subject_id' => '16',
            'title' => 'Assignment',
            'due_date' => '2012-03-30',
            'status_id' => '7',
            'notes' => '',
            'score' => '83',
            'weighting' => '50',
            'deleted' => '0',
            'created_on' => '2012-03-30 02:54:48',
            'modified_on' => '2012-04-02 03:10:27',
          ),
        ),
      )),
       'meta' => 
      Gas\Data::__set_state(array(
         'collections' => 
        array (
          'entities' => 
          array (
            'subject' => 
            array (
              'path' => '\\Model\\Coursework=>\\Model\\Subject',
              'pivot' => NULL,
              'child' => '\\Model\\Subject',
              'type' => 'belongs_to',
              'single' => true,
              'options' => 
              array (
              ),
            ),
            'user' => 
            array (
              'path' => '\\Model\\Coursework=>\\Model\\User',
              'pivot' => NULL,
              'child' => '\\Model\\User',
              'type' => 'belongs_to',
              'single' => true,
              'options' => 
              array (
              ),
            ),
            'status' => 
            array (
              'path' => '\\Model\\Coursework=>\\Model\\Status',
              'pivot' => NULL,
              'child' => '\\Model\\Status',
              'type' => 'belongs_to',
              'single' => true,
              'options' => 
              array (
              ),
            ),
          ),
          'fields' => 
          array (
            'id' => 
            array (
              'rules' => 'max_length[10]',
              'callbacks' => 
              array (
                0 => '_auto_check',
              ),
              'annotations' => 
              array (
                0 => '10',
                1 => 'INT',
                2 => 'unsigned',
                3 => 'auto_increment',
                4 => '',
              ),
            ),
            'users_id' => 
            array (
              'rules' => 'max_length[10]|integer',
              'callbacks' => 
              array (
              ),
              'annotations' => 
              array (
                0 => '10',
                1 => 'INT',
                2 => '',
              ),
            ),
            'subject_id' => 
            array (
              'rules' => 'max_length[10]|integer',
              'callbacks' => 
              array (
              ),
              'annotations' => 
              array (
                0 => '10',
                1 => 'INT',
                2 => '',
              ),
            ),
            'title' => 
            array (
              'rules' => 'max_length[255]',
              'callbacks' => 
              array (
                0 => '_char_check',
              ),
              'annotations' => 
              array (
                0 => '255',
                1 => 'VARCHAR',
                2 => '',
              ),
            ),
            'due_date' => 
            array (
              'rules' => '',
              'callbacks' => 
              array (
              ),
              'annotations' => 
              array (
                0 => '',
              ),
            ),
            'status_id' => 
            array (
              'rules' => 'max_length[10]|integer',
              'callbacks' => 
              array (
              ),
              'annotations' => 
              array (
                0 => '10',
                1 => 'INT',
                2 => '',
              ),
            ),
            'notes' => 
            array (
              'rules' => '',
              'callbacks' => 
              array (
                0 => '_char_check',
              ),
              'annotations' => 
              array (
                0 => 'TEXT',
                1 => '',
              ),
            ),
            'score' => 
            array (
              'rules' => 'max_length[3]|integer',
              'callbacks' => 
              array (
              ),
              'annotations' => 
              array (
                0 => '3',
                1 => 'INT',
                2 => '',
              ),
            ),
            'weighting' => 
            array (
              'rules' => 'max_length[3]|integer',
              'callbacks' => 
              array (
              ),
              'annotations' => 
              array (
                0 => '3',
                1 => 'INT',
                2 => '',
              ),
            ),
            'deleted' => 
            array (
              'rules' => 'max_length[1]|numeric',
              'callbacks' => 
              array (
              ),
              'annotations' => 
              array (
                0 => '1',
                1 => 'TINYINT',
                2 => '',
              ),
            ),
            'created_on' => 
            array (
              'rules' => '',
              'callbacks' => 
              array (
                0 => '_date_check',
              ),
              'annotations' => 
              array (
                0 => 'DATETIME',
                1 => '',
              ),
            ),
            'modified_on' => 
            array (
              'rules' => '',
              'callbacks' => 
              array (
                0 => '_date_check',
              ),
              'annotations' => 
              array (
                0 => 'DATETIME',
                1 => '',
              ),
            ),
          ),
          'collumns' => 
          array (
            0 => 'id',
            1 => 'users_id',
            2 => 'subject_id',
            3 => 'title',
            4 => 'due_date',
            5 => 'status_id',
            6 => 'notes',
            7 => 'score',
            8 => 'weighting',
            9 => 'deleted',
            10 => 'created_on',
            11 => 'modified_on',
          ),
        ),
      )),
       'related' => 
      Gas\Data::__set_state(array(
         'collections' => 
        array (
        ),
      )),
       'ts_fields' => 
      array (
        0 => 'modified_on',
        1 => '[created_on]',
      ),
       'unix_ts_fields' => 
      array (
      ),
    ))
.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases