CodeIgniter Forums
DataMapper 1.6.0 - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Libraries & Helpers (https://forum.codeigniter.com/forumdisplay.php?fid=22)
+--- Thread: DataMapper 1.6.0 (/showthread.php?tid=11358)



DataMapper 1.6.0 - El Forum - 01-30-2009

[eluser]wolffc[/eluser]
I noticed that datamapper does a SELECT * from table LIMIT 1 when i create an object. I am guessing it does this to find the columns. Can I just predefine my columns in the model so i don't have to do that query or an option to turn it on or off?


DataMapper 1.6.0 - El Forum - 01-30-2009

[eluser]OverZealous[/eluser]
I bet you would find, if you compared it, that that query takes so little time that it doesn't make much difference — it takes about 2ms on one of my testing server's tables. (Unless your DB is in a different datacenter...)

It's actually CodeIgniter doing it, using the driver. Also, DM has been optimized to only call this once (the first time a specific type of model is created). If yours is making more than one query per model, make sure you are using the latest version of DM (1.6.0 as of this posting).

To disable it you'd have to edit DataMapper itself, as it is central to the constructor.


DataMapper 1.6.0 - El Forum - 01-31-2009

[eluser]Murodese[/eluser]
[quote author="OverZealous.com" date="1233356920"]I bet you would find, if you compared it, that that query takes so little time that it doesn't make much difference — it takes about 2ms on one of my testing server's tables. (Unless your DB is in a different datacenter...)

It's actually CodeIgniter doing it, using the driver. Also, DM has been optimized to only call this once (the first time a specific type of model is created). If yours is making more than one query per model, make sure you are using the latest version of DM (1.6.0 as of this posting).

To disable it you'd have to edit DataMapper itself, as it is central to the constructor.[/quote]

Yeah, 0.2ms for that query on our production server Smile

It's not really an issue.


DataMapper 1.6.0 - El Forum - 02-02-2009

[eluser]bEz[/eluser]
I'm not able to key in the appropriate search term, so I'm posting my question meanwhile I continue my search attempts.

I'm relatively still new to the CI framework, however, I've decided to develop with DM (despite the restraints of join tables).

I understand that there is a method of utilizing multiple databases in the CI core, however,
what is the method (if possible) of using multiple databases with Datamapper?


DataMapper 1.6.0 - El Forum - 02-02-2009

[eluser]Daniel H[/eluser]
How would I create a relationship whereby one object can relate to two separate instances of another object. For example, for I want to link - say - a 'post' object to two 'user' objects: one that has created the post, and another that last edited the post.

Or perhaps a 'task' could be 'owned' by a user, but also 'assigned' to another user?

Any ideas?


DataMapper 1.6.0 - El Forum - 02-02-2009

[eluser]OverZealous[/eluser]
@Daniel H
Currently, there is no way to have the different relationships to the same object without subclassing the duplicated object, as if it were a self-reference.

It depends on what your needs are, but the basic way to do this is to create your objects like so:
Code:
class User extends DataMapper {
    $table = 'users';  // here for clarity, not required
    $model = 'user'; // ditto
    // add in validation, etc.
}

class EditingUser extends User { // note, extends User!
  $table = 'users'; // required!
  $model = 'editinguser'; // here for clarity, not required
  // nothing else is needed in this class
}

class Task extends DataMapper {
   $has_one = array( 'user', 'editinguser' );
}

Now your table is a little trickier:
Code:
-- this joining table is named after the TABLE for users
CREATE TABLE tasks_users (
    id SERIAL NOT NULL,
    task_id integer NOT NULL,
    user_id integer,
    editinguser_id integer
);
That table will handle both of the joins.

There is one important drawback: the EditingUser cannot be used for other join operations! DataMapper will always look for editinguser_id on the joins, so you can't, for example do this:
Code:
$task = new Task();
$task->get_by_id(10);
// assume a user has multiple phone numbers
$task->editinguser->get()->phonenumber->get();
That will fail because there is no editinguser_id column on the phonenumbers_users table.

@bEz
You don't need to shout it ;-), but DataMapper does not have any built-in mechanisms for dealing with multiple DataBases. What is it, exactly, you are trying to achieve? Cross DB queries? Look up in one then the other?

DataMapper uses the same DataBase library as CI, so you might be able to hack something in by replacing the Model's db element:
Code:
// do queries on default DB
$obj = new Object();
$obj->get();
// now query alternate database
$obj->db = $this->load->database('other_db', TRUE);
$obj->get();
// obj2 will still be using the default database.
$obj2 = new Object();
If you ALWAYs need a different database for a specific model, you could create a custom constructor, like so:
Code:
class Thing extends DataMapper {
    function Thing() {
        parent::DataMapper();
        $CI =& get_instance();
        $this->db = $CI->load->database('otherdb', TRUE);
    }
}

(I haven't tested this, these are just ideas that might work for you)


DataMapper 1.6.0 - El Forum - 02-02-2009

[eluser]Daniel H[/eluser]
Thanks overzealous, so I think the most sensible thing is to have an 'owner' and an 'editor' object which have 1-1 relationships with a user. I don't want to start using dm in a way it isn't designed to work.

I can't imagine this would be that much of an overhead, and keeps thing pretty clean anyway...

Cheers.


DataMapper 1.6.0 - El Forum - 02-02-2009

[eluser]OverZealous[/eluser]
I creating sub-classes is OK for DM. It's the only way, for example, to create a self-reference.

That being said, your solution is fine (I've thought of doing it myself), however, it does add a few new queries into each lookup, possibly even adding many queries on loops.

If you use the 1-1 relationsips, due to the 5th-form join tables, you now have to query:
- Once for the list of tasks
- Once for the Owner object
- Once for the Owner's User object
- Once for the Editor object
- Once for the Editor's User object

Obviously, this could be problematic looping through a large set. Using the subclass method is only 3 queries, unless you need access to the EditingUser has_one or has_many elements.


DataMapper 1.6.0 - El Forum - 02-02-2009

[eluser]bEz[/eluser]
@OverZealous.com
Actually, I thought I formatted it with a whisper tag ;-)

Seriously though, thanks for the reply. I'm trying to utilize DM with my app, however the user table is in another database (phpBB3).

Keep in mind I'm new to the CI (frameworks as a whole) method of coding. So my concern was that in the learning curve, whether the DM (ORM) was capable of doing multiple DBs like CI core does it.

I'm more likely to need access to the forum db for more than just login purposes, so "ALWAYS ON" method is what I'm trying to acheive. My alternative solution would be to develop my with one of the "AUTH" library releases.

I will head back to my dev lab and test the methods provided. It's likely that my ALWAYS ON choice is actually not that, but rather a quick read to synchonize with the main/default db.

-bEz


DataMapper 1.6.0 - El Forum - 02-02-2009

[eluser]OES[/eluser]
OK related Object Count is just not playing ball for me.

I have 3 tables as follows

ads | zones | ads_zones (relationship table)

They relate no prolem for normal gets etc but I cannot count the ads which are active related to the zone. Folling the User guide on the I just keep gettings erros.

Here is my code.

Code:
// Create new Ad Object
$a = new Ad();

// Create new Zone Object and get by the ID of 1
$z = new Zone();
$z->get_by_id(1);

// Populate my var with the count where ad is active.
$count = $z->ad->where('active', TRUE)->count();

SQL error is showing its trying to count the active field in the related table ?? I know in needs to count the reated fields but the where should be on the ad table.

Here is SQL error.

Code:
Unknown column 'ads.active' in 'where clause'

SELECT COUNT(*) AS `numrows` FROM (`ads_zones`) WHERE `ads`.`active` = 1 AND `zone_id` = '1'

I just cant understand why its creating this query.

Really hope you can help. Have lost a few hours on this one.

Thank you in advance.