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 - 10-24-2008

[eluser]OverZealous[/eluser]
I have not upgraded yet (Thanks for letting me know about it, though ;-) ), but I would suggest using:
Code:
$item->select('*', TRUE);

That TRUE turns off identifier protection.

If that works, you might want to change it within DataMapper for now, until a better fix can be found.


DataMapper 1.6.0 - El Forum - 10-24-2008

[eluser]dexcell[/eluser]
[quote author="OverZealous.com" date="1224801997"]Yes, you have the correct idea for example 1 - you need a dedicated table with [id] for data, and a dedicated table for each relationship. There, currently, is no way to store or retrieve data stored in a relationship table.

If you do this, you almost certainly will need to see my extension of DataMapper above, which allows you to add relationships to queries (where_related). It looks like commandercool is working on a fix for the relationship tables, but I'm not sure how easy it is to implement that yet.

Also, you might want to create an in-between subclass of DataMapper so you can add tweaks to all of your models. If you look back up the thread, there are examples of how to do this. (Basically, I created a class called DataMapperExt that extends DataMapper. Then all your models subclass DataMapperExt - you can name it anything you want.)

For example 2:
It gets trickier when doing self-referencing tables, but not too difficult. There are good examples of this in the DataMapper documentation. The process is:

Create the User model like normal.
Create a Friend model. This model should subclass User, and explicitly set $table to "users".
Add "user" to Friend::$has_many in the Friend constructor
Add "friend" to User::$has_many in the User constructor
Create a table called friends_users, with the columns (id, friend_id, user_id).

Now you can get the friends of a user through $user->friends->get. Note, however, the Friend models will not be able to dig deeper without being converted into Users. There isn't an easy solution to this, yet.

Good Luck![/quote]

Thanks for your answers Smile

I would like to ask is there any tool to help me migrating the table (currently have records in it) to match the DataMapper table requirement (ie. dedicated table for each relationship).

I am interested using this datamapper just after reading the userguide because it's looks like easy to use and have power, but currently i have many tables with many relationship using foreign key, it's a bit pain in the ass to change it manually without tool Big Grin


DataMapper 1.6.0 - El Forum - 10-24-2008

[eluser]OverZealous[/eluser]
I don't know of any tools. You could look for some kind of database normalization tool, but I doubt it would work.

I know that pain, though. Just get through it - it doesn't take quite as long as you might think ;-P .


DataMapper 1.6.0 - El Forum - 10-24-2008

[eluser]ntheorist[/eluser]
@dexcell

Here's how you would set up your tables in your example:

table list

object tables

users ( id, username)
languages (id, language )
entries ( id, content )
friends ( id, mute, field2, field3, etc. )

linking tables

languages_users ( id, language_id, user_id )
friends_users (id, friend_id, user_id )
entries_users (id, entry_id, user_id )
entries_languages (id, entry_id, language_id )

Models - the models need to relate both ways, ie if user->has_one['language'] then language must has_one['user'] or has_many['user']

user.php :

Code:
has_one = array('language');
has_many = array('entry','friend');
entry.php :
Code:
has_one = array('user','language');
friend.php :
Code:
has_one = array('user');
language.php :
Code:
has_many = array('user','entry');

it can be a pain to port foreign keys over to the new table setup. I've already had to deal with it and haven't even tried to find any software to do it for me. what i usually do is write a script in a temporary controller that does it. It just reads the table with the keys and creates INSERT statements that i can just dump into PhpMyAdmin or something, so in your example (using CI's active record from a controller) here's what you could do to parse the 'entries' table you had with the foreign keys :

Code:
// table 'entries' - (id, user_id(FK), language_id(FK), content)

$this->db->from('entries');
$query = $this->db->get();

foreach($query->result() as $row)
{
    $sql = "INSERT INTO `entries_languages` SET `entry_id` = '".$row->id."', `language_id` = '".$row->language_id."' LIMIT 1;";
    $sql2 = "INSERT INTO `entries_users` SET `entry_id` = '".$row->id."', `user_id` = '".$row->user_id."' LIMIT 1;";

    echo $sql . br() . $sql2 . br();
}

that should spit out all the insert statements you just copy/paste and dump into the database. Just do that for every table that has keys, and write it up to insert into the linking table for each key.. so if you have 4 FKs you'll create 4 separate INSERT statements

then when that's run, just drop the user_id and language_id columns from 'entries' and you should be fine.

also, you could optionally create each $sql statement and then run $this->db->query($sql), or even run
Code:
$this->db->insert('entries_languages',array('entry_id'=>$row->id,'language_id'=>$row->language_id));
but personally i like to see the statements it creates before running them, since i want to make sure they're correct.

CC


DataMapper 1.6.0 - El Forum - 10-25-2008

[eluser]dexcell[/eluser]
^
Thank you overzealous and CC Smile


DataMapper 1.6.0 - El Forum - 10-27-2008

[eluser]Maxximus[/eluser]
To be able to use Datamapper with CI 1.7 with the buggy backticks, you need some changes in DM:

Code:
function select($select = '*', $protect_identifiers = FALSE) // was TRUE

in function _changed:
$this->db->select($field, FALSE); //AR FALSE parameter added

in function _related:
$this->db->select($this->table . '.*', FALSE); //AR FALSE parameter added
After that, everything functions as usual again.


DataMapper 1.6.0 - El Forum - 10-27-2008

[eluser]steelaz[/eluser]
[quote author="Maxximus" date="1225124037"]To be able to use Datamapper with CI 1.7 with the buggy backticks, you need some changes in DM:

Code:
function select($select = '*', $protect_identifiers = FALSE) // was TRUE

in function _changed:
$this->db->select($field, FALSE); //AR FALSE parameter added

in function _related:
$this->db->select($this->table . '.*', FALSE); //AR FALSE parameter added
After that, everything functions as usual again.[/quote]

I think this is fixed in latest SVN, so if you update your CI system folder you won't have to modify DM


DataMapper 1.6.0 - El Forum - 10-28-2008

[eluser]The Hamburgler[/eluser]
Hi,
I've played about with datamapper in a few different projects. Its worked great!
However I've recently hit a bit of a problem whenever I try to access a relationship.

Quote:Fatal error: Call to a member function get() on a non-object in .../application_store/controllers/Welcome.php on line 46

The offending code seems to be $c->product->get(). For some reason "product" is not being recognized as an object.
Code:
// load up the category model
$this->load->model('Category');
                
// create new Category model
$c = new Category();
        
// select chosen category
$c->where('id', $cat_id)->get();
                
// Populate the related catergory object with all related products
$c->product->get();

The two Datamapper models I have are as follows

Code:
class Category extends DataMapper {
    
    var $has_many = array('product' => 'products');    
    var $table = "categories";    
    
    function Category()
    {
        parent::DataMapper();
    }
}

Code:
class Product extends DataMapper {
    
    var $has_one = array('category' => 'categories');
    
    function Product()
    {
        parent::DataMapper();
    }
}

I'm running datamapper 1.3.4 as I can't find a link to the latest 1.4.5 build.
Thanks


DataMapper 1.6.0 - El Forum - 10-28-2008

[eluser]ntheorist[/eluser]
yeah the stensi.com site still doesn't have the latest version to download.. i'm attaching v 1.4.5 here.

as for your models, i dunno at what point the relation arrays changed, but right now you should only specify the model names in the array (no associative keys), so it should be:

Code:
// Category Model
var $has_many = array('product');
and
Code:
// Product Model
var $has_one = array('category');

lemme know if that works for you.

CC


DataMapper 1.6.0 - El Forum - 10-28-2008

[eluser]The Hamburgler[/eluser]
Nice one, a combination of changing the relationship arrays and upgrading to 1.4.5 worked a treat :-)