I have a many to many with an additional table that will contain additional data. This means that this is now a many2one with one2many relationship for the middle model.
I have Agency and Users. And an additional model AgencyUsers which will hold the relation with an additional attribute `status` for example.
So the question is how to use CRUD to save data to the Agency variable when I have all of the User objects. If the ->save method of the AgencyUsers is not called then the Agency->save will throw a frozen Object.
Another issue is the complex key - it cannot allow primary keys from the foreign keys, and this is an issue as when I want to find the exact AgencyUsers the find method cannot be called (with array($agecy_id, $user_id)) but should be query()ed;
If you add a model in between instead of a through table, you need to use that as well:
// assume an existing user and agency $user = Model_User::find(1); $agency = Model_Agency::find(1);
// construct a new through object with a default status $user->agency_users = Model_AgencyUsers::forge(array('status' => 0));
// assign the agency to the user $user->agency_users->agency[] = $agency;
// save, this should cascade $user-save();
Your Model_AgencyUsers is a separate model, so it requires a unique PK. user_id and agency_id are both FK's in this model, and may not be part of the PK.
CRUD is an abbreviation of a computer principle that applies to a single object (create, read, update, delete).
If you want to apply that to a one-to-many relation, you'll need a form with two sections: an upper part containing the parent data, and below rows of child records. Fieldset has support for that via tabular forms, which works fine together with ORM relations.
Btw, may be I messed the relationships?? Should it be:
(one to many - many to one) Agency has many Agency_Users User has many Agency_Users Agency_Users belongs to Agency Agency_Users belongs to User
or its the (many to one - one to many) Agency belongs to Agency_Users User belongs to Agency_Users Agency_Users has many Users Agency_Users has many Agencies
Note that I tend to make the relation name plural for a "many" type of relation, and singular for a has_one or a belongs_to. Just a rule I have for our devs, it makes it instantly clear whether or not you need to use array notation.
This will provide you with direct access from User to Agency and vice-versa, AND access to the join table if needed.
To directly relate an agency with a user. Note that this only works if your join table has default values for all other columns in that table. If not, you'll have to resort to using the join table directly:
No need to relate anything, you have a model for your join table, so you can create it directly. (obviously, in this example the find's aren't needed because you have the PK's, but it's an example).
An alternative is to create the base join object, and relate it:
So you see, you can have plenty of options you can play with. Which one is best, probably depends on the objects you have already loaded, or which PK's you already have, to minimize the number of queries you have to run.
The most straitforward is my first example in my previous post, with a many-many relation, which you can ignore the presence of your join table model until you actually need it.
You can even define conditions on the relation if needed, so you could make a relation that only gives you agencies with a join status of 0, and a second relation with agencies with a join status of 1.
Basically, in the relation definition in your model, you can add a 'conditions' section, which is an array that takes "order_by" and "where" clauses, which are injected into the JOIN when you query the relation.
I vaguely remember an issue with identifying the through table, but I can't find the thread that discussed it at the moment (problem is ORM aliasses all tables).