You currently have: Person -> has_many -> (via join_person_car) <- has_many <- Car (a many-many between Car and Person).
If Wheel is something specific about the combination of a car and a person, from a normalisation point of view it should be related to the join table, and not to either Person or Car.
This means you have to make a model for the join table (let’s call that PersonCar), otherwise you can’t relate something to it.
You now get:
- Person -> has_many - <- has_one <- PersonCar
- Car -> has_many - <- has_one <- PersonCar
This will still be a many to many between Person and Car. If you define a custom tablename of ‘join_person_car’ for the PersonCar model, you don’t even have to change the many to many for direct access via Person or Car.
Now that you have this, you can relate other models of PersonCar:
- PersonCar -> has_one -> Wheel (which has wheel_id in PersonCar)
No guarantees, I only don’t make any promisses towards maintaining it.
I don’t write (new) CI applications anymore, and I haven’t used the extension in years. But the DM code is very stable, and as CI itself hardly changes, there isn’t much to maintain, and I don’t see it breaking any time soon. Unless CI 3 is going to “pull a kohana”, but I don’t think so…
:( But i´m not very clear… you will keep DM ORM mantained?
Abot what you said… you dont prefer CI anymore, what do you recommend us then?
Hello, I’m using the login example listed on the datamapper website. What I’m trying to build now is a function to allow users to change their password. I want the user to input their current password before allowing a new password to be saved. Simply saving a new password for the user works fine:
The model in the example is using a validation rule to encrypt the password, using the function _encrypt() in the model.
The login() method in the model shows you how a salt is determined and how a password entered by the user is encrypted so it can be compared to a stored password.
WanWizard, i have a doubt, i know any ORM make slow any aplication… But i want to know if there is a big difference between using CI ActiveRecord and using DM? and if there is possible to mix CI AR in DM Models? i.e. to make simple queries.
Any extra layer costs performance, and an ORM is no exception.
Whether or not that is an issue, depends on your situation. My company creates (large) business applications, the hourly rate of the developers by far outweighs the extra cost of a more beefy server. If you work for free, then ymmv.
Datamapper is quite fast, the biggest overhead is instantiating all objects. So using an ORM for batch operations is a bad idea. Also, use PHP 5.4, since it’s a lot faster when using objects.
Mixing AR and DM isn’t a problem, DM uses AR underneath. You can even convert an AR resultset into DM objects if you want.
I’ve been playing with datamapper for a little while now and I’m really loving how easy it makes things. I had my own core model that handled some of this before, but DM ORM is much more powerful. All credit to you!
I have a question - I have some fairly complex relationships in my system. Part of the system is based around a decision tree. So a tree has many questions, and question has many answers, plus others I won’t bother explaining.
I’m adding a concept of revisions into the system, so now each tree / question / answer also has one revision. When I create a new revision, I need to duplicate the data for each of the entities and update the revision to the latest revision id so we have a complete history of all entities.
What I’m not sure about is how to handle the relationships. The code below uses get_copy on each entity, updates the revision id and save it again but obviously this won’t account for any relationships.
Following normal normalisation rules, I would probably split the record into question and revision, using a one-to-many.
It would keep the rest of the system, up to question, the same, and you can easily get the latest revision of the question using either the id or a timestamp by running a query with a DESC order, LIMIT 1.
For easy access you could store the last revision id in the question record, and use two relations: one for the one-to-many to get all revisions of a question, and a one-to-one using that last revision id as FK to directly fetch the last revision of a question.
I don’t think there should be a revision in the tree, as it’s a property of the question.
The reason I’ve done it the way that I have is that all trees / questions / answers (and also products, and product attribute values that I didn’t explain before) should have a full revision history so the admins can press a button and restore all of the values for those entities back to their previous state. To my mind that means we need to store a revision ID for all of entities - what do you think?
What I was really looking for is a way to handle the copying of the entities and their relationships. Is there a good way of doing that with DM ORM?
Hello WanWizard and congrats for DataMapper (it has speeded up my work). I have a question that maybe is answered in v2.0 input request, but want to clear any doubt. Let me explain: all my model objects extend DataMapper class and all of them share a set of methods. The question is obvious: I want to write those methods just once, is there any way to do this?
I’ve tried:
class MY_DataMapper extends DataMapper { public function my_shared_method() { // ...method stuff... } }
Then:
class Model_1 extends MY_DataMapper { // ...model stuff... }
But error: “PHP Fatal error: Class ‘My_DataMapper’ not found” appears.
It’s fine Harro, I had done exactly as you wrote, but name convetion was responsible for non-functioning. Actuallly my Model_Base was LB_Entity, stored in application/models/lb_entity.php
Renaming to Lb_Entity was enough.
Sorry for disturbing, as it would have worked from the begining if I had considered class naming convention.