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.

Data Model Questions

Multiple many_many relations


Go to End
Reply

9 Posts   2951 Views

Avatar
neros3

18 August 2010 at 12:48am (Last edited: 19 August 2010 10:09pm), Community Member, 51 Posts

Hi

--- EDIT ---
Just in order to make my problem clear to everyone.
What I'm trying to do here is having 2 lists of Members on a class. This is because I want to have a list of administrators and a list of users. I could also, if possible, put a boolean on the relation table indicating wheater the member is admin or not. But I havent found a way to "decorate" the relation table...

Thanks again - Any input is appreciated!

I have decorated the standard Member class with DataObjectDecorator. I have an entity that has a many_many relation with Member.

Group : many_many(Members =>Member)
Member : belongs_many_many(Groups => Group)

The relation table created (Group_Members) contains ID, GroupID and MemberID. I would like to add another field to the relation to tell if a Member in the Group is Admin in this specific Group. Since a Member can belong to several Groups the field can not be on the Member.

I have also tried to have two Member lists (GroupAdmins and GroupMembers) - But the fix with class.field doesn't seem to apply for the many_many/belongs_many_many relation (http://open.silverstripe.org/ticket/4632)

Any ideas?

Thank you!

Avatar
neros3

19 August 2010 at 10:19pm (Last edited: 19 August 2010 10:32pm), Community Member, 51 Posts

I realize that I could extend the member class and use that 'subbed' class for one of my lists... But that is just an ugly solution to my problem. I would prefer the boolean setting on the relation table...

Avatar
MarcusDalgren

21 August 2010 at 12:02am Community Member, 288 Posts

Just to clarify, why aren't you using group roles for this?

Is there something in the way you're doing things that makes it impossible to use the standard role system to put someone in a group and then figure it out from there?

Avatar
neros3

24 August 2010 at 2:07am Community Member, 51 Posts

Hi Smurkas

Thanks for your reply!

Perhaps I've got this all wrong. But Roles can only be applied to Groups.

Lets say its a page for soccer teams. Then for each Team I would have to create 2 groups and apply a custom role (isAdmin) on the one group and add my user to either one of the groups.

So soccer team could have "AdminGroup" => "Group" and "MemberGroup" => "Group".

Then perhaps just making a Member wrapper that has the boolean (isAdmin) and has_one Member would be a better idea?

What do you think?

Thanks!

Avatar
MarcusDalgren

24 August 2010 at 2:34am Community Member, 288 Posts

Actually scratch what I wrote before.

So you have your own DataObject or Page (I'm guessing) that's linked to Member through a many_many. So assuming you called your connection to Member "Contacts":

   public static $many_many = array(
      "Contacts" => "Member"
   );

   static $many_many_extraFields = array(
      "Contacts" => array("IsAdmin" => "Boolean")
   );

Now you can use that boolean to split the member list.
Also as you noted the fix you found doesn't apply to many_many and the fix has not been merged back in so that functionality isn't currently available in SilverStripe.

Avatar
neros3

24 August 2010 at 5:47am Community Member, 51 Posts

Thank you!

Exactly what I was looking for! One thing though, I can't use the extra field in the template ($IsAdmin gives me nothing). If I Debug::show($member) its there nicely, but in the template its not.
Any idea why this is? I was considering to make a function isAdmin($member) but I can't use arguments for functions... is this correct?

Thanks!

Avatar
MarcusDalgren

24 August 2010 at 6:00am Community Member, 288 Posts

Yes that's correct.

I'm not sure if I've ever actually used a value from a join table in the template. What you can do is write your own getter for it.
If you need to get it off of the Member object then you decorate Member with your own method. I'd use SQLQuery to fetch it manually if it isn't available through $member->IsAdmin.

class MemberDecorator extends DataObjectDecorator {
   public function IsAdmin() {
      // If the property is available directly on the object
      return $this->owner->IsAdmin;
      // Otherwise put together an SQLQuery and fetch it
      $sqlQuery = new SQLQuery();
      $sqlQuery->select("IsAdmin")->from("join_table")->where("MemberID = ".$this->owner->ID);
      $result = $sqlQuery->execute();
   }
}

Something like that I think.

Avatar
neros3

24 August 2010 at 8:53pm (Last edited: 24 August 2010 8:54pm), Community Member, 51 Posts

Hi Smurkas!

Thanks for the reply!

Funny thing happens when i add:

$this->Members()->add(Member::currentUser(), array('IsAdmin' => '1'));


The added user is not me, but another user (user id = 4 - my user id is 1).
If I remove the extra field array from the add it works like it should.

Have you heard of this before?

Thanks!

Go to Top