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]
  • #991 / Jul 21, 2014 6:21am

    Maglok

    402 posts

    There are a lot of methods that use the id property. One of them being get_by_id() for example. You can always use get_by_FIELD() instead for that one.

    Thing is that statements like ‘$this->db->where(‘id’, $this->id);’ are all over the code. The only way I see to change that behaviour is to define the name of the id as a variable and use that everywhere instead. But that is an aweful lot of ‘work’.

    An example with for example the delete() function. It immediately grabs the id of the current Object, then iterates over its relations and makes liberal use of the id field with $this->id. After which it deletes the object itself with:

    // Delete the object itself
        $this->db->where('id', $this->id);
        $this->db->delete($this->table);

    So it is possible, but a buncha work. Maybe editing thie CIBonfire is easier?

  • #992 / Jul 21, 2014 6:43am

    imohammad

    8 posts

    Convinced 😊

    Modifying CiBonfire seems much more easier.

    Thanks Simon!

    There are a lot of methods that use the id property. One of them being get_by_id() for example. You can always use get_by_FIELD() instead for that one.

    Thing is that statements like ‘$this->db->where(‘id’, $this->id);’ are all over the code. The only way I see to change that behaviour is to define the name of the id as a variable and use that everywhere instead. But that is an aweful lot of ‘work’.

    An example with for example the delete() function. It immediately grabs the id of the current Object, then iterates over its relations and makes liberal use of the id field with $this->id. After which it deletes the object itself with:

    // Delete the object itself
        $this->db->where('id', $this->id);
        $this->db->delete($this->table);

    So it is possible, but a buncha work. Maybe editing thie CIBonfire is easier?

  • #993 / Jul 21, 2014 7:10am

    Maglok

    402 posts

    It is of course a matter of personal taste, but I do like ‘id’ as the identifier myself. SQL allows differently, but I have always seen it as sort of a default, a guideline if you will. 😊

    Good luck!

  • #994 / Jul 21, 2014 7:13pm

    imohammad

    8 posts

    Thanks man!

    I ended up using another table called Groups. Will leave role for default users and admins only. I modified CIbonfire but didnt work for me. more than 300 files :S

    I have another question, welcoming an answer from everyone 😊

    Now If I have a table called User and another table called User_profile, how to link both together?

    So that I can join both tables together whenever I want.

    Please note that I don’t have a table called profile nor a model called profile.

    It is of course a matter of personal taste, but I do like ‘id’ as the identifier myself. SQL allows differently, but I have always seen it as sort of a default, a guideline if you will. 😊

    Good luck!

  • #995 / Jul 22, 2014 3:04am

    Maglok

    402 posts

    You got a table called User and a table called User_profile. You make two datamapper extending classes using the template file.

    Then you can create new instances of those tables with:

    $user = new User();
    
    // Get all users
    $user->get();

    Now you need to create a relationship between the two. If it is a 1 on 1 (which seems likely) you can add a user_id foreign key to the User_profile table. Then in the datamapper code create a simple relationship as in the manual.

    You can then access your profile info like so:

    $user = new User();
    
    // Get all users
    $user->get();
    
    // Get specific data from profile
    echo $user->user_profile->address;

    That any help?

  • #996 / Jul 24, 2014 9:58am

    imohammad

    8 posts

    Thank you Simon! really appreciate your help.

    I somehow asked the wrong question 😊 but glad you answered again.

    Anyway, I’m having a problem since yesterday with joining many to many relations.

    I have the following tables:
    Groups
    Groups_Users
    Skills
    Users
    Skills_Users

    I want to get a list of users based on the group filter and skill filter

    What I tried:

    $group = new Group();
    $user = new User();
    $skill = new Skill();
    
    $group->where('title', 'dev')->get();
    $skill->where('title', 'php');
    $skill->where('title', 'java');
    
    $user->where_related($group)->get() // retrieves all users in dev group
    $user->where_related($skill)->get(); // retrieves all users either in dev group or not with the above skills

    I could do this using sql statements easily, but I’m trying to get my head around this whole ORM for my work.

    You got a table called User and a table called User_profile. You make two datamapper extending classes using the template file.

    Then you can create new instances of those tables with:

    $user = new User();
    
    // Get all users
    $user->get();

    Now you need to create a relationship between the two. If it is a 1 on 1 (which seems likely) you can add a user_id foreign key to the User_profile table. Then in the datamapper code create a simple relationship as in the manual.

    You can then access your profile info like so:

    $user = new User();
    
    // Get all users
    $user->get();
    
    // Get specific data from profile
    echo $user->user_profile->address;

    That any help?

  • #997 / Jul 24, 2014 10:07am

    Maglok

    402 posts

    Yeah I know how ORM needs a bit of a different approach in thinking.

    So you want users that have a certain skill and/or a certain group. You can do that like this:

    // Instance your objects
     $group = new Group();
     $user = new User();
     $skill = new Skill();
     
     // Get a bunch of groups
     $group->where('title', 'dev')->get();
     
     // Combine the get for the skills and get them
     $skill->where_in('title', array('php', 'java'))->get();
     
     // Get the set that has the related $group and the related $skill
     $this->where_related($group)->where_related($skill)->get();

    This is just a example, I didn’t test it. 😊

    And important thing is to remember that you cannot just do another get() on a instance of a datamapper object and expect it to remember the previous result.

  • #998 / Jul 24, 2014 2:28pm

    imohammad

    8 posts

    I had no idea that you can use where_related multiple times.
    You have been a huge help for me during this learning process and I’m so thankful Simon!

    Let me make the same previous example but a bit harder.

    Let’s say we want the same result in the previous example and in addition, we want to filter them by their rates.

    So I have the following tabe (in addition to the previous tables):
    
    Users_rates
    
    
    Users_Rates Columns:
    - ID
    - User_id
    - rating

    And we want to calculate the average of the rating for each user, and we filter the retrieved users based on the average rate.

    Users_Rates dummy data:
    1
    1
    4
    
    2
    1
    5
    
    3
    2
    3
    
    4
    2
    5

    And I want to include the average column with the result. I don’t think I can use Include_related()? because this is a one to many relation.


    I’m thinking of all possible examples, and I’m thankful for your help a lot!


    - Mohammed

    Yeah I know how ORM needs a bit of a different approach in thinking.

    So you want users that have a certain skill and/or a certain group. You can do that like this:

    // Instance your objects
     $group = new Group();
     $user = new User();
     $skill = new Skill();
     
     // Get a bunch of groups
     $group->where('title', 'dev')->get();
     
     // Combine the get for the skills and get them
     $skill->where_in('title', array('php', 'java'))->get();
     
     // Get the set that has the related $group and the related $skill
     $this->where_related($group)->where_related($skill)->get();

    This is just a example, I didn’t test it. 😊

    And important thing is to remember that you cannot just do another get() on a instance of a datamapper object and expect it to remember the previous result.

  • #999 / Jul 25, 2014 4:49am

    Maglok

    402 posts

    I have to admit I am not sure I grasp your question 100%.

    Let’s see what I can make of it. 😊

    You have a table where you store what user has rated what/how high.

    I am not sure what you mean by ‘the average column’ I do not see a average column in your example.

    I might be going off-road here but seems to me you have to setup your datamodel as the following, see some useage examples below as well:

    // Setup a User model
    // Setup a Group model
    // Setup a Skill model
    // Setup a Rating model
    
    // Setup relations so that a User has many Groups, Skills and Ratings
    
    // Create a new user
    $user = new User();
    
    // Get a specific user with ID 5
    $user->get_by_id(5);
    
     // Access data from that user
     foreach($user->rating as $rating)
     {
      echo $rating->rating; // Print the rating column of the current rating
     }
     
     // You could also write a function in your User model that returns the average of all the ratings from that user
     // In User model
     public function average_rating()
     {
      // Get all the ratings and put them in a single array
      $ratinginfo = $this->rating->all_to_single_array('rating');
      
      // Add them all up
      $sum = array_sum($ratinginfo);
      
      // Calculate the average and return it
      return ($sum / sizeof($ratinginfo));
     }
     
     // You can also try a approach to getting a average by calculating it in the constructor once and then assigning it as a value of Rating
     // User constructor
     public function __construct()
     {
      parent::__construct();
      
      $this->average_rating = $this->average_rating();
     }

     

  • #1000 / Aug 28, 2014 5:28am

    lovestorms

    3 posts

    Hi all,
    I’m new at datamapper and i need your help.

    Model:

    class Details extends DataMapper
    {
     var $table = 'details';
     public $has_many = array('box');
     public $validation = array(
      'price' =>array(
       'rules'=>array('required')
      ),
      'as' =>array(
       'rules'=>array('required')
      ),
      'is_sbox' =>array(
       'rules'=>array('required')
      ),
      'month' =>array(
       'rules'=>array('required')
      ),
      'type' =>array(
       'rules'=>array('required')
      ),
      'date_time' =>array(
       'rules'=>array('required')
      ),
     );
    }
    
    class box extends DataMapper
    {
     var $table = 'box';
     public $has_one = array('details');
     
     public $validation = array(
      'username' => array(
       'rules'=>array('required')
      ),
      'passport_no' => array(
       'rules'=>array('required')
      ),
      'address' => array(
       'rules'=>array('required')
      ),
      'phone' => array(
       'rules'=>array('required')
      ),
     );
    }

    Control:

    function contracts(){
      
      $c = new Details();
      $s = new Box ();
    
      $c->where('type','3')->get();
      $s->where_related('details', 'id', $c)->get();
    
                
             $this->load->view('admin/contracts');
     }

    Error:

    Error Number: 1146
    
    Table 'testdb.details_box' doesn't exist
    
    SELECT `box`.* FROM (`box`) LEFT OUTER JOIN `details_box` details_box ON `box`.`id` = `details_box`.`box_id` WHERE `details_box`.`details_id` IN (64, 66, 67, 68, 86, 88)

    Thank you

  • #1001 / Aug 28, 2014 7:02am

    Maglok

    402 posts

    Hey there,

    Datamapper is trying to find a join table named details_box between details and box.

    Something that also pops is that you are doing a where_related with $c as parameter while that should be a value not a object.

    It could be that your database does not have the correct schematic. Could you post that?

  • #1002 / Aug 28, 2014 11:49pm

    lovestorms

    3 posts

    Hi, there are my table

    Details:
    
    id 
    price 
    id_box
    type (1:buy, 2:rent)
    
    Box:
    
    id
    account
    password
    email
    nickname

    I set relation both of them in model is $has_many. I want join table details with table box without create new table detail_box.

    Control:

    $box = new Box;
    
    $box->include_related('details', 'id_box');
    
    //$box->get_iterated(); 
    $box->get();

     

     

     

  • #1003 / Aug 29, 2014 2:42am

    Maglok

    402 posts

    There are two ways to create a relation, the has one and the has many.

    The has many requires a join table between the two.

    The has one requires the class that has one to have a column called field_id. So in your case that would be box_id. Unfortunately it is hardcoded in datamapper that it has to be field_id, so try renaming your id_box into box_id. 😊

  • #1004 / Sep 03, 2014 11:59pm

    lovestorms

    3 posts

    There are two ways to create a relation, the has one and the has many.

    The has many requires a join table between the two.

    The has one requires the class that has one to have a column called field_id. So in your case that would be box_id. Unfortunately it is hardcoded in datamapper that it has to be field_id, so try renaming your id_box into box_id. 😊

    Thank you! I have fix it.

    How about join 3 or more table? It use a same way?

  • #1005 / Sep 04, 2014 3:00am

    Maglok

    402 posts

    That is trickier. There are two ways to do that.

    First option: You create join columns in the table and use them like join fields. That way is not that good though, since then you will have a ID and you still need to get() the actual object.

    Second (and in my opinion better) option: Instead of just a join table you create the join table with 3+ joins and you define it as a datamapper model. This is a difficult concept so let me give an example:

    We have a Project, Person and Role. Lets say we want a Person to get a Role in a Project. The Role is a list of options from the database.
    
    We have Project, Person and Role as Datamapper objects. But we need a join table with the project_id, person_id and role_id. We name the join table Project_person_role.
    
    Then we make a datamapper model for Project_person_role.
    
    Project_person_role
    has one: Project
    has one: Person
    has one: Role
    
    Project
    has many Project_person_role
    
    Person
    has many Project_person_role
    
    Role
    has many Project_person_role
.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases