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]
  • #31 / Mar 22, 2012 5:16am

    toopay

    1583 posts

    @Khrome83 and @Dan Tdr

    To answer your question, if I use this code, where the only thing that changed is that all() is replaced with find(1), i get errors.

    Code -

    $skills = Model\Skills::find(1);
       $this->output->enable_profiler(TRUE); 
    
       foreach ($skills as $s) {
        echo $s->name.'
    ';
        foreach ($s->types() as $t){
         echo $t->name.'
    ';
        }
        foreach ($s->professions() as $p) {
         echo $p->name.'
    ';
        }
        foreach ($s->weapons() as $w) {
         echo $w->name.'
    ';
        }    
        //wtf($s);
    
       }

    Outputs -

    A PHP Error was encountered
    
    Severity: Notice
    
    Message: Trying to get property of non-object
    
    Filename: views/welcome.php
    
    Line Number: 69
    
    
    
    Fatal error: Call to a member function types() on a non-object in /home/guildwar/public_html/application/views/welcome.php on line 70

     

    Obviously, you are trying to itterate object there, not an array. Try :

    // Here you are try to find one record
    $this->output->enable_profiler(TRUE); 
    $skill = Model\Skills::find(1);
    
    foreach ($skill->types() as $t)
    {
      // Do your job with $t here
    }

    Hey toopay,

    I searched for this info but with no luck, how can i use Gas ORM 2 with HMCV (Modular Extension) i want to put my models in my modules and not keep them in a folder models in my application folder. How can i do that?

    Thank you,
    Dan

    Khrome83 already pointed to the right section. For example you have “foo” and “bar” module, located in application/modules, you could have something like this :

    $config['models_path'] = array(
       'Model' => APPPATH.'models',
       'Model\\Foo' => APPPATH.'modules/foo/models',
       'Model\\Bar' => APPPATH.'modules/bar/models',
    );

    If your modules located outside your application folder, just modify the location with an absolute path within your modules.

  • #32 / Mar 22, 2012 5:35am

    toopay

    1583 posts

    EDIT: It doesn’t work even if I make that change by hand, so the problem is somewhere else. I’m probably doing something stupid here, but it did work with the previous Gas ORM version.

    EDIT2: Am I supposed to somehow define the foreign key here? service_type table has a column called id and service has type_id. Is this what breaks it? Why did it work in the previous version though?
    I’m actually quite new to databases and ORM, so bear with me here.

    From information you provide, let say you have it set up this way right now

    1. Service entity
      Table name : service
      Model name : Model\Service
    2. Service type entity
      Table name : service_type
      Model name : Model\Service_type

    In Model\Service

    // Because you dont have service_type_id field, 
    // you should define the foreign key…
    public $foreign_key = array('\\model\\service_type' => 'type_id');
    
       //... in relationship declaration
       'service_type' => ORM::belongs_to('\\Model\\Service_type'),

    In Model\Service_type

    //... in relationship declaration
       'service' => ORM::has_many('\\Model\\Service'),

     

  • #33 / Mar 22, 2012 5:45am

    indCI

    11 posts

    From information you provide, let say you have it set up this way right now

    1. Service entity
      Table name : service
      Model name : Model\Service
    2. Service type entity
      Table name : service_type
      Model name : Model\Service_type

    In Model\Service

    // Because you dont have service_type_id field, 
    // you should define the foreign key…
    public $foreign_key = array('\\model\\service_type' => 'type_id');
    
       //... in relationship declaration
       'service_type' => ORM::belongs_to('\\Model\\Service_type'),

    In Model\Service_type

    //... in relationship declaration
       'service' => ORM::has_many('\\Model\\Service'),

    Alright, thanks for the help!

    What about the auto-generated version where it’s \Model\Service\Type and not \Model\Service_type?
    Does the same apply to that or should it work without defining the foreign key?

  • #34 / Mar 22, 2012 5:56am

    toopay

    1583 posts

    What about the auto-generated version where it’s \Model\Service\Type and not \Model\Service_type?

    Regarding the auto-generated thing, other member already asked similar questions, and i already explain in this post and this post. Personally, this convention make it easier for me to distinguish a general tables and a pivot tables. If it was within some folder, then it must be a pivot table 😊

    Does the same apply to that or should it work without defining the foreign key?

    Yes the same apply, except, you may need to also specify the table name on Model\Service\Type :

    public $table = 'service_type';
  • #35 / Mar 22, 2012 7:16am

    indCI

    11 posts

    Another thing, I had to retrieve records that match a datetime BETWEEN two datetimes and a certain foreign key.
    In the last version I used

    $this->find_where( 'starting BETWEEN "' . $date . '" AND "' . $to_date . '" AND resource_id=' . $resource_id );</code></pre>
    I'm not sure if that was best practice but it worked.
    There doesn't seem to be a find_where method in Gas 2 though.
    How should I achieve this?
    
    <span style="font-size:9px;"><i>EDIT: Ah, figured it out. If anyone needs it, here's how I wrote it now. (Unless there's a better way to do it.)
    <pre><code>ModelName::where( 'starting BETWEEN "' . $date . '" AND "' . $to_date . '"' )->find_by_resource_id( $resource_id );

    EDIT2: Scratch that. It did not work it just translated to this. Still don’t know how to do it.

    SELECT * FROM (`ModelName`) WHERE `resource_id` =  2

    EDIT3: Alright I put it in a single CI AR query, so that works at least, but shouldn’t find_by_column be chainable with them? Or is all() the only gas method that’s chainable with CI query builder?

    ModelName::where( 'starting BETWEEN "' . $date . '" AND "' . $to_date . ' 23:59:59" AND resource_id=' . $resource_id )->all();
  • #36 / Mar 22, 2012 8:37am

    Dan Tdr

    20 posts

    @Khrome83 and @Dan Tdr

    Hey toopay,

    I searched for this info but with no luck, how can i use Gas ORM 2 with HMCV (Modular Extension) i want to put my models in my modules and not keep them in a folder models in my application folder. How can i do that?

    Thank you,
    Dan

    Khrome83 already pointed to the right section. For example you have “foo” and “bar” module, located in application/modules, you could have something like this :

    $config['models_path'] = array(
       'Model' => APPPATH.'models',
       'Model\\Foo' => APPPATH.'modules/foo/models',
       'Model\\Bar' => APPPATH.'modules/bar/models',
    );

    If your modules located outside your application folder, just modify the location with an absolute path within your modules.

    Thanks for the reply, the thing is that i can`t add every single module in the config path because i want to allow users to develop/add modules of their own, and that would mean that the path would have to change every time someone ads a module, can’t it be done like gas orm 1.x done it? give it a folder and search for models in that folder? Or is there any other way to do this?

    Thanks

    Edit 1:

    i added in config/gas.php, created the models with gas orm

    $config['models_path'] = array(
    //'Model' => APPPATH.'models',
    'Model\\News' => APPPATH.'modules/news/models'
    );

    and i am trying to access it from the news controller:

    public function migrate(){
    // FINDER  
    $all_users = Model\News::all();
    var_dump($all_users);
    }

    and i get this in my error log

    [b][22-Mar-2012 12:45:11 UTC] PHP Fatal error:  Class 'Model\News' not found in /home/bogdan/public_html/beta/system/cms/modules/news/controllers/news.php on line 81[/b]

    what am i doing wrong?

    Thanks

  • #37 / Mar 22, 2012 9:32am

    toopay

    1583 posts

    EDIT3: Alright I put it in a single CI AR query, so that works at least, but shouldn’t find_by_column be chainable with them? Or is all() the only gas method that’s chainable with CI query builder?

    ModelName::where( 'starting BETWEEN "' . $date . '" AND "' . $to_date . ' 23:59:59" AND resource_id=' . $resource_id )->all();

    Yeah, thats the right way to do it. find_by_something is a convinience method to find some record(s) based by a specific field, and it is already contain a single where clause. Its not chainable with other where clause, but it does chainable with most of other CI query builder(limit, group_by etc).

    find_where is removed, to avoid redundant API due the availability of any other where method which inherit from CI query builder.all is similar with get in CI query builder, so it could chainable with most of CI query builder.

  • #38 / Mar 22, 2012 10:04am

    toopay

    1583 posts

    and i am trying to access it from the news controller:

    public function migrate(){
    // FINDER  
    $all_users = Model\News::all();
    var_dump($all_users);
    }

    and i get this in my error log

    [b][22-Mar-2012 12:45:11 UTC] PHP Fatal error:  Class 'Model\News' not found in /home/bogdan/public_html/beta/system/cms/modules/news/controllers/news.php on line 81[/b]

    what am i doing wrong?

    Thanks

    Nothing wrong with the log. You couldn’t access something that not exists. From your configuration above Model\News is the root of your news modules, right? You supposed to have model like : application/modules/news/models/foo.php contain :

    <?php namespace Model\News;
    
    use \Gas\Core;
    use \Gas\ORM;
    
    class Foo extends ORM {
      //... field and relationship declarations
    }

    then you could call foo model from whereever controller within your application :

    $foo = Model\News\Foo::all();

    If, somehow you dont want to specify each of your module’s models, you still can do that. But maybe your naming convention will be slightly akward, i think you could have this on models_path :

    $config['models_path'] = array(
       'Model' => APPPATH.'models',
       'Model\\Module' => APPPATH.'modules'
    );

    Then, for example you have bar model on foo module :

    <?php namespace Model\Module\Foo\Models;
    
    use \Gas\Core;
    use \Gas\ORM;
    
    class Bar extends ORM {
      //... field and relationship declarations
    }

    And i think you could call bar model using :

    $bar = Model\Module\Foo\Models\Bar::all();

    Not looks natural right? But well, at least that work, if its what you need. Since HMVC is not a natural/native part of CI, i can’t think other solution than that, in your specific case.

    This version use PHP 5 autoloader, so its more efficient rather than the previous version, which recursively scanning the model folder 😊

  • #39 / Mar 22, 2012 10:12am

    Dan Tdr

    20 posts

    awesome, i was forgetting to add the news class at the end, thanks for taking the time to explain it all to me, you`ve done great work, i fallowed gas orm since it`s first release, saw version 2.0 on github but the lack of documentation when i first saw the 2.0 version made me wait. It`s great that you had the time to develop this orm 😊
    Congratz.

  • #40 / Mar 22, 2012 11:07am

    toopay

    1583 posts

    Yes, this ORM still lack of documentation (compare to something like CI Datamapper). I know, LAZY IS OUR VIRTUE, but i was hoping everyone also look at the classes/source code (since i was put comments/annotations block everywhere, and i think that would be prety much helped), to get deeper knowledge how this ORM works, or what APIs available either in the core classes or/and in extension classes. I will try to answer, if one of you need some clarification on that.

    However, i’ve just got some email from NetTut, replied to my Gas ORM tutorial pitching. That mean in near time, i will share some point regarding this ORM in those tutorial site. I would share most of important thing in this ORM, how you all should use this ORM in your CodeIgniter application and hopefully that tutorial could be a legacy for any CI developer who use this ORM 😊

  • #41 / Mar 23, 2012 2:30am

    indCI

    11 posts

    Would a wiki type user guide work?
    People could share their knowledge and you could comment on best practices.

    It’s not always clear from the source code what the intended use is, so a documentation and/or some examples help a lot if you’re new to these. Especially the examples.

  • #42 / Mar 23, 2012 3:24am

    indCI

    11 posts

    There are hooks for saving and deleting records, to do something with it before it goes through, but is it possible to hook reading records?

    I’m working with a database where names and descriptions are stored as serialized arrays of localized strings. When I read records from there, I have to unserialize it and choose the right locale. I would like to do this automatically somewhere before it goes to my model or whatever code is reading the records.

    EDIT:
    Answering myself again, after going through the source for a while it looks like I could use the __get property overloading.

  • #43 / Mar 27, 2012 3:18am

    indCI

    11 posts

    When reading records and looping through them with foreach, like in the example in the CRUD section of the User Guide, the foreach will fail if only one row matched the query.

    Do I have to manually check each time to see if it returned an object or an array, and place the object in an array if not?
    Is there a simpler way to make sure I always get an array even if there is just one row?

  • #44 / Mar 27, 2012 5:38am

    toopay

    1583 posts

    I have this simple extension as a convinience way to interact with result.

    Simply create a file in the application/libraries/gas/extension/result.php contain above snippet, then you can use it as follow :

    $result = Model\ORM\User::result()->all();
    
    // Easy way to debug over your result
    echo $result;
    
    // Convert the instances into an array of instance
    $users = $result->as_array();
    
    foreach ($users as $user)
    {
      // $user will be a typical Gas Instance
    }
    
    // Convert all instance's record into various format
    $records_array = $result->to_array(); // assoc array
    $records_json = $result->to_json();   // JSON 
    $records_xml = $result->to_xml();     // XML
    
    // Convert all instance's record into Gas\Data object
    $records_data = $result->to_data();
    
    $first_user = $records_data->get('data.0'); // Return the first index
    $first_user_name = $records_data->get('data.0.name'); // Return the first index name
    $some_user_name = $records_data->get('data.100.name', 'Default Name');
    // And so on…
  • #45 / Mar 28, 2012 3:14pm

    Khrome83

    22 posts

    @Khrome83 and @Dan Tdr

    To answer your question, if I use this code, where the only thing that changed is that all() is replaced with find(1), i get errors.

    Code -

    $skills = Model\Skills::find(1);
       $this->output->enable_profiler(TRUE); 
    
       foreach ($skills as $s) {
        echo $s->name.'
    ';
        foreach ($s->types() as $t){
         echo $t->name.'
    ';
        }
        foreach ($s->professions() as $p) {
         echo $p->name.'
    ';
        }
        foreach ($s->weapons() as $w) {
         echo $w->name.'
    ';
        }    
        //wtf($s);
    
       }

    Outputs -

    A PHP Error was encountered
    
    Severity: Notice
    
    Message: Trying to get property of non-object
    
    Filename: views/welcome.php
    
    Line Number: 69
    
    
    
    Fatal error: Call to a member function types() on a non-object in /home/guildwar/public_html/application/views/welcome.php on line 70

     

    Obviously, you are trying to itterate object there, not an array. Try :

    // Here you are try to find one record
    $this->output->enable_profiler(TRUE); 
    $skill = Model\Skills::find(1);
    
    foreach ($skill->types() as $t)
    {
      // Do your job with $t here
    }

    Hey toopay,

    I searched for this info but with no luck, how can i use Gas ORM 2 with HMCV (Modular Extension) i want to put my models in my modules and not keep them in a folder models in my application folder. How can i do that?

    Thank you,
    Dan

    Khrome83 already pointed to the right section. For example you have “foo” and “bar” module, located in application/modules, you could have something like this :

    $config['models_path'] = array(
       'Model' => APPPATH.'models',
       'Model\\Foo' => APPPATH.'modules/foo/models',
       'Model\\Bar' => APPPATH.'modules/bar/models',
    );

    If your modules located outside your application folder, just modify the location with an absolute path within your modules.

    @toopay -

    Thanks for the feedback.

    So multiple objects are returned as a array because I am asking for all().
    If I use find, it returns a object in the object…

    So how can I make my code universal for reading 1 or many objects?

    For example, if i have the same page to display 1 as I do many (the view) but the model either gets all or a limited number, even a specific entry, then I have to test to see if it’s a array before presenting, or should I do a conversion to make it a array with a single entry?

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

ExpressionEngine News!

#eecms, #events, #releases