Multiple has_ones of the same class

Multiple has_ones of the same class

Creating multiple has_one relations to the same class is no problem whatsoever. You can easily do something like this:

class Child extends DataObject {
	static $has_one = array(
		'Father' => 'Person',
		'Teacher' => 'Person'
	);
}

From the Child's point of view this will work fine, creating a FatherID and a TeacherID in the DataBase, both pointing to a Person object. But what happens when you want to query these relations the other way around, from the Person point of view?

Normally you'd just create a has_many relation within the Person class that points to the Child class and SilverStripe will automatically map it to the one existing has_one relation. But of course now there are two! The following will not work, SilverStripe has no way of knowing to which has_many points to which has_one and will probably go map everything to 'Teacher', the last has_one in line:

// Don't do this!
class Person extends DataObject(
	static $has_many = array(
		'Children' => 'Child',
		'Pupils' => 'Child'
	);
)

Use dot-notation!
For that to work you have to explicitely map the Children to the Father and the Pupils to the Teacher and you can actually achieve that by using dot-notation like this:

// Do this instead:
class Person extends DataObject(
	static $has_many = array(
		'Children' => 'Child.Father',
		'Pupils' => 'Child.Teacher'
	);
)

Now the following template will work:

<% control Children %>  ... <% end_control %>

<% control Pupils %> ... <% end_control %>

Conclusion: for each has_one you need a complementary has_many, and by using dot notation on the has_many side you can tell SilverStripe whch couple belongs together. In fact you now have two one-to-many relations both involving the same two classes! See this post if you want to use separate complexTableFields to manage thes type of relations.

Comments

Het versturen van reacties is uitgeschakeld.

RSS feed voor reacties op deze pagina