gabordemooij / redbean

ORM layer that creates models, config and database on the fly
https://www.redbeanphp.com
2.31k stars 279 forks source link

shared list with other name then the tablename #181

Closed hanselsen closed 12 years ago

hanselsen commented 12 years ago

Hi there,

I don't know if im at the right place, but I'm having an issue with my shared lists. Im having a 'training' which has to have 2 sharedlists with the same types. So I want something like this: $training->sharedTrainer = R::batch('member', array(111,112)); $training->sharedTrainee = R::batch('member', array(222,223)); But I thing I only can do this: $training->sharedMember = R::batch('member', array(222,223)); Anybody know how to solve the above problem?

Tnx in advance

nirgavish commented 12 years ago

what was your solution? please share, as i'm facing the same issue

gabordemooij commented 12 years ago

Possible Solution: $training->ownMember = array( $trainer, $trainee ); $trainer->role = 'trainer'; $trainee->role = 'trainee';

In this case both trainer and trainee are members but with different role properties. Other solutions are possible as well. I cant tell you the optimal solution because that depends on the context.

nirgavish commented 12 years ago

that is very informative, but i'm not sure it's exactly right for me. here's my issue:

i have 2 tables: projects and users

users can be attached to projects as many to many (ie: a project may have many users, and a user may have many projects.

each user has a role in each project (ie: owner, admin, client, staff etc.)

i need a logical place to store the connection type, rather than just keeping a generic connection

any thoughts?

gabordemooij commented 12 years ago

Whenever you need to qualify an N-M relation, you are actually using an 1-N and N-1 relation. In other words; you miss the intermediate bean.

Your domain model is telling you there is a missing entity. In this case this could be a participant. That makes sense. A user is never 'born' with a role. A role is only valid in the context of a project. So you have a user, referring to a 'person' and you have a participant referring to someone participating in the project. The participant then HAS a user (the real person) and it HAS a project thus forming the relationship. I often encounter this fallacy because later on the domain will require more qualifications (i.e. what percentage of the profit will a participant get? not the user, how much long has the participant been associated with the project? - not the user etc...)

The structure then becomes:

$project->ownParticipant = array($teacher,$trainee);

//or the other way around: $teacher = R::dispense('participant'); $teacher->project = $project $teacher->role = 'teacher'; $teacher->user = $user;

If the participant types have very different properties you can split them into two entities: teachers and trainees, which resembles my previous solution.

Sometimes you just want to qualify the relation. While I see this as a risky solution it is possible to do with RedBeanPHP. I hid this feature from plain sight because it often got abused in the past, you'll find it here:

http://www.redbeanphp.com/manual/association_api

Look for extended associations. With extended associations you can properties to associations. Personally I find that a very dangerous approach but it looks like this:

R::associate($user,$project,array('role'=>'teacher'));

To retrieve:

R::$extAssocManager->related($project,'user'); -- returns the junction

The API for extended relations also might be a bit clunky at times.

Hope this helps, plz let me know if you require some more assistance.