I have a DataObject
called Applicant
and it $has_one
Member
(this is the SilverStripe Member
class).
private static $has_one = array (
'MemberApplicant' => 'Member'
);
When a member is logged in and visits the ApplicationPage
I want to be able to populate the form based on the members Applicant
data.
I can make this work but I feel like I should be able to access the data easier.
Here is what I do:
$memberID = Member::currentUserID();
$applicant = Applicant::get()->filter('MemberApplicantID', $memberID)->first();
$form->loadDataFrom($applicant);
Shouldn't I be able to instantiate a Member
and then call its relative $MemberApplicant
?
Shouldn't I be able to instantiate a Member and then call its relative $MemberApplicant?
Of course. I assume you have a 1:1 relation, then you have to define the counter part on Member
using $belongs_to
(see this diagram)
class Applicant extends DataObject
{
private static $has_one = [
'MemberApplicant' => 'Member'
];
...
class MemberApplicantExtenension extends DataExtension
{
private static $belongs_to = [
'Applicant' => 'Applicant'
];
...
Now add the DataExtension to the Member object in /mysite/_config/config.yml
Member:
extensions:
- MemberApplicantExtenension
and run a dev/build?flush.
Now you're able to get the related Applicant from the Member using built in ORM magic:
//Get the current Member
$member = Member::CurrentUser();
//get the $belongs_to
$applicant = $member->Applicant();
It sounds like you want to be able to avoid an "additional" ORM query by going through the current user's Member
record, however this is not how SilverStripe (Or any system that uses SQL JOIN
s works).
When you add a $has_one
to a class, you essentially add a foreign key to that class's table. In your case it will be called MemberApplicantID
, which is a foreign key to the Member table's primary key - its ID
field. Thus your ORM query needs to go through an Applicant
instance first.
Caveat: The above is not entirely true, DataObject
does allow you to define a private (SilverStripe config) static $belongs_to
on your model classes which lets you query "The other way around". I've never actually done this before, but it does look like you'd declare this on a custom DataExtension
that decorates Member
and has a value of "Applicant". See DataObject::belongsToComponent()
.
You can also simplify your existing ORM query slightly without having to instantiate a DataList
explicitly, but the route to your target data remains the same:
// SilverStripe >= 3.2
$applicant = DataObject::get_one('Applicant', array('MemberApplicantID = ?' => $memberID));
// SilverStripe < 3.2
$applicant = DataObject::get_one('Applicant', '"MemberApplicantID" = ' . $memberID);