gabordemooij / redbean

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

2-way relationships with beans #228

Closed F21 closed 11 years ago

F21 commented 11 years ago

Currently, this is the behaviour

$account = R::dispense('account');
$email = R::dispense('email');
$email->account = $account;

var_dump($email->account); //We get a bean
var_dump($account->ownEmail); //empty array

Since we are passing a bean to $email->account, it would be possible to set up a relationship in the passed bean ($account) to the accepting bean $email.

This makes it easier when we use a model to represent account and need to access ownEmail from the account model without having to load the bean from the DB:

var_dump($email->account); //We get a bean
var_dump($account->ownEmail); //Get an array of email beans
gabordemooij commented 11 years ago

Interesting idea. Not sure if this is wise (introduces an awful amount of magic) but I need to think about this.

F21 commented 11 years ago

Any further thoughts on this?

gabordemooij commented 11 years ago

It's basically like implementing the identity map pattern; I am not sure if this makes things easier or more complex. That's the whole thing with ORM; many features that seem obvious at first don't work out because of accidental complexity. In this case for instance; how are we gonna track those beans; how does the user know a bean is 'an old one' versus one freshly loaded from the database? Do we need additional management tools to force a bean to update (what if you explicitly request two beans representing the same record)? Do you have to be able to merge-in 'external beans' so they will be recognized as having been loaded previously (like Doctrine offers) ? That's the first problem.

The second problem is I don't like leaky abstractions; either we hide all of SQL or we cooperate with traditional SQL. This feature seems to be on the 'hiding side' of the spectrum. If I implemented this feature it would make RedBeanPHP more like a traditional ORM - we pretend there is no database, no SQL and the objects magically map onto records. I don't think that's a good model for RedBeanPHP, it does not try to hide SQL, only provide some powerful tooling. Instead of hiding SQL, RB tries to build a bridge between the OOP paradigm and the SQL paradigm. This is why SQL can be used throughout the system. Features like this basically lie to users: when you set $book->ownPage[] = $page, you're basically adding a record with a book_id, however the $book->page bean has not bean loaded yet. Should we return the newly created $page? It has not been stored in the database yet; so that would be weird. Unless you pretend there is no database of course; but guess what we still have to use SQL....?!

These are just some thoughts I am writing down. I might play with this feature (someone already asked for the identity map pattern as well) and experiment but I can't guarantee it will be in the next release. Not sure whether it's good for RedBeanPHP.