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 - 05-31-2009

[eluser]tdktank59[/eluser]
very true. I forgot completely about that... Thanks for the tip!


DataMapper 1.6.0 - El Forum - 05-31-2009

[eluser]tdktank59[/eluser]
Did we ever get that bug fixed where we had to save the main object before creating a relationship with it?
The only reason I ask is im not able to test my scripts right now...
And on another note... If it doesnt work yet we should put it on the dev path for DMZ or DM
aka:

Code:
$role = new Role();
$role->name = $name;

$permission = new Permission();
$permission->where_in('id',$permissions);

$role->save($permission->all);

Also does the save($permission->all); have to be $permission if only 1 row exists? instead of permission->all


DataMapper 1.6.0 - El Forum - 05-31-2009

[eluser]OverZealous[/eluser]
[quote author="tdktank59" date="1243847576"]Did we ever get that bug fixed where we had to save the main object before creating a relationship with it?[/quote]

This is not a bug. You cannot save a relationship to a non-existant object.

However, you can already do the example you provided. This simply saves the current object (if changed or new), and then immediately saves the relationship(s). If you are having trouble with that, then you have a bug somewhere. Always check the boolean result of $object->save()

Quote:Also does the save($permission->all); have to be $permission if only 1 row exists? instead of permission->all

$permission is always the same thing as the first item in $permission->all.


DataMapper 1.6.0 - El Forum - 05-31-2009

[eluser]tdktank59[/eluser]
Cool, thanks


DataMapper 1.6.0 - El Forum - 06-08-2009

[eluser]Khoa[/eluser]
Firstly, I have to say thank as this is one of the best libraries ever! Great job!

But I have an issue that I've been trying to find in this post but could not as it has about 90 pages :cheese: ! So I will post it again here, sorry if it has been asked.

I think it is something about saving relationships and object itself at the same time, and also a bit to do with transactions.

The situation is, for blog we need to save tags for entry, entry has many tags, tags have many entries and so on. I've done the saving new entry bit, it's fine, but when it comes to edit an existing entry which already has a number of tags, it seems a bit tricky to me.


SITUATION:

1. Entry has a validation rule that tag is required
2. Entry 1 has been created with 4 tags: tag1, tag2, tag3 and tag4
3. User updates it and clears all the tag. This should fail and all tags stay there.


WHAT I DID:

Code:
$entry = new Entry();
$entry->get_by_id($id);

// (D) Delete all existing tags inside memory
$entry->tag->delete_all();

// (L) Then loop through new tags coming from post and add them in.
// Nothing in this case as user does not enter anything

// Finally save the changes of other details like title, etc.
$entry->save();


WHAT HAPPENED:

- It does not allow user to save as it does not pass validation (requires tag). This is GOOD.
- However, all tags are gone because they have been deleted before the validation happens! This is BAD.


WHAT I EXPECTED:

- Display a message saying that tag is required
- Nothing changes in the DB, no tag is deleted.


QUESTION:

- How could I update the entry->tag without changing the DB so that when validate() runs at the save() command, it fails and nothing changes?

I tried to use transactions like this but no luck:

- trans_begin()
- delete()
- trans_rollback()

Transaction does not recover records that have been deleted when rolling back.

Thanks.


DataMapper 1.6.0 - El Forum - 06-08-2009

[eluser]OverZealous[/eluser]
Khoa
What database are you using? I'm pretty certain this works under PostGreSQL (with manual transactions), but I don't use MySQL, so maybe someone else could pipe in on that. DataMapper relies entirely on the database (and CodeIgniter) for transactions.

Also, do you have automatic transactions enabled on DataMapper? That may or may not have an effect.

Finally, you might just want to do a manual check before attempting the delete. I know the library is supposed to handle it, but it might be the only option if your database is incorrectly handling transactions.

This is a more complete sample of the manual transaction code that should work:
Code:
$entry = new Entry();

// start a transaction
$entry->trans_start();
$entry->get_by_id($id);
// delete all tags
$entry->tag->delete_all();

// Attempt to save, this should throw an error
if($entry->save()) {
    $entry->trans_commit();
    // redirect, etc.
} else {
    $entry->trans_rollback();
    // show error
}



DataMapper 1.6.0 - El Forum - 06-08-2009

[eluser]Khoa[/eluser]
Hi Phil,

I use MySQL and I set automatic transactions DISABLED.

I notice one thing in your code, it says:

$entry->trans_start();

But inside the documentation, it says:

$u->trans_begin();

Is it just because you typed it on the rush Smile or it is what you actually do and it works?

Khoa


DataMapper 1.6.0 - El Forum - 06-08-2009

[eluser]OverZealous[/eluser]
Yup - that's just me typing from memory quickly. It's start / complete or begin / rollback / commit!
Smile

Otherwise, it looks like everything else is correct. I would try to test the MySQL code directly, by running something like this (on a test DB):

Code:
START TRANSACTION;
DELETE FROM `entries_users` WHERE `user_id` = 1;
ROLLBACK;
SELECT * FROM `entries_users` WHERE `user_id` = 1;

(Again, this is hand-written from memory, so it may be incorrect.)

If you get the correct output, then the issue might be with CodeIgniter's transaction code. If you get an error, or the incorrect result, make sure you are using transaction-capable tables (which I'm sure you already are!).

Beyond that, I can't think of any other reasons it would fail. I haven't heard of anyone else having trouble, but that doesn't mean too much!


DataMapper 1.6.0 - El Forum - 06-08-2009

[eluser]Khoa[/eluser]
Phil, I think I figure out what's wrong! It is because of the table type. It has to be set as InnoDB in order for it to support transactions as only innoDB and BDB are transaction-safe tables while others are nontransaction-safe. By default, the table type is MyISAM which is nontransaction-safe or in other words, DOES NOT SUPPORT tractions.

http://dev.mysql.com/doc/refman/5.0/en/storage-engines.html

I'm at work now, so just tried it directly with phpmyadmin. Will go home and test it out with DM. But it seems to be the solution :-)

However, I notice on thing with transactions. Even records are not changed when transaction rolls back, if there is INSERT statement happened, the id column does increase and this does not roll back. Eg, if we have 10 inserts inside transactions, then roll back, the next time it inserts successfully, the id is not continuous anymore (there is a gap of 10). Not a big deal, but is it normal?


DataMapper 1.6.0 - El Forum - 06-08-2009

[eluser]Khoa[/eluser]
Phil, I think we just typed our 2 posts at the same time, LOL! Big Grin