Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Managing 1 to 1 relationships


Reply


3 Posts   478 Views

Avatar
AdamJ

Community Member, 145 Posts

28 October 2012 at 8:56pm

Hi friends,

I'm building out my first SS 3.0 site, and am finding a new enjoyment to coding in SilverStripe which is awesome.

One part of the new site I'm building is wanting to add in UI to manage a 1 to 1 relationship. Looking at the core dev discussions there was some discussions previously saying that true 1 to 1 relationships weren't supported but the general consensus was something that the team wanted added.

Is there a way to achieve it in 3.0?

For a bit of context, I have a location dataobject that describes practice locations for a collective of surgeons, but I wanted to use the same location object to attach to the contact page to describe the collective's general office details.

This is the specifics in terms of the relationships:

Surgeon has_many Locations

ContactPage has_one Location

Location has_one Surgeon
Location has_one ContactPage

I'd prefer to not have to embed a copy of the location fields into the contactpage - which is the only way I know how to achieve it now. If I can though I'd prefer to be a bit smarter about this. Ideally, I'd love to be able to have the Location forms embedded in the admin UI for the ContactPage, so the user could edit the general ContactPage information, as well as the Location information with a single save.

Thoughts?

Avatar
Carbon Crayon

Community Member, 598 Posts

29 October 2012 at 10:33pm

Hi Adam,

I think I understand what you want and I don't think you need a true 1 to 1, all you need is the Contact Page to have one Location. The location doesn't need a Contact Page because you won't ever be going in that direction. So I think you can just do:

ContactPage has_one Location

Then within the contact page context you can call <% with Location %> in the template.

Also is 'Surgeon' a collective or a single surgeon within a collective? If it's the former I think you want this:

Location has_many Surgeons
Surgeon has_one Location

Or, if a Surgeon can have multiple locations:

Location many_many Surgeons
Surgeon belongs_many_many Locations

Moving on to wanting to edit the location directly in the ContactPage you can do this using onBeforeWrite. If you add some fields to getCMSFields() without adding them to the $db static, you can use their values in onBeforeWrite() to write them to the accociated Dataobject, like so:

   
   public function getCMSFields()
   {
      $fields = parent::getCMSFields();
      
      if($location = $this->Location())
      {
         $fields->addFieldToTab('Root.Main', new TextField('LocationName', 'Location Name', $location->Name));            
      }
      
      return $fields;
   }

   public function onBeforeWrite()
   {
      parent::onBeforeWrite();
      
      if($location = $this->Location())
      {
         $location->Name = $this->LocationName;         
         $location->write();
      }
   }

Hope that helps :)

Aram

www.SSBits.com - SilverStripe Tutorials, Tips and other bits

Avatar
AdamJ

Community Member, 145 Posts

29 October 2012 at 10:59pm

Edited: 29/10/2012 11:02pm

Hey Aram,

Thanks for the reply mate!

I think I understand what you want and I don't think you need a true 1 to 1, all you need is the Contact Page to have one Location. The location doesn't need a Contact Page because you won't ever be going in that direction.

Oh ok! I just assumed you need to specify the relation on the other side to make it a true relationship.

Also is 'Surgeon' a collective or a single surgeon within a collective? If it's the former I think you want this:

Actually a Surgeon can have multiple locations, but a location belongs to only one Surgeon, so 1-many.

Moving on to wanting to edit the location directly in the ContactPage you can do this using onBeforeWrite. If you add some fields to getCMSFields() without adding them to the $db static, you can use their values in onBeforeWrite() to write them to the accociated Dataobject, like so:

Oh awesome idea! I didn't even think of that. I'll give that a whirl.