Jump to:

3430 Posts in 1057 Topics by 734 members

Data Model Questions

SilverStripe Forums » Data Model Questions » Has_one but belongs_many_many

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

Page: 1
Go to End
Author Topic: 2004 Views
  • Stefdv
    Avatar
    Community Member
    110 Posts

    Has_one but belongs_many_many Link to this post

    Hello,

    Here's my issue;

    Dog has_one Pedigree
    Dog belongs_many_many Pedigrees //A dog is the parent or grandparent of an other dog so belongs in a pedigree

    Pedigree has_many Dogs //One pedigree can be for several dogs, like from one litter
    Pedigree many_many Dogs //the pedigree has many dogs, Parents, grandparents, greatgrandparents

    I manage my dogs with modeladmin, but the above relations give me time_out errors. I guess the problem lies in the fact that i create a loop. Edit a dog, create a pedigree that could hold the same dog i'm editing

    Isn't this possible ?

  • swaiba
    Avatar
    Forum Moderator
    1784 Posts

    Re: Has_one but belongs_many_many Link to this post

    Hi Stefdv,

    this looks fine...

    Dog has_one Pedigree
    Pedigree has_many Dogs //One pedigree can be for several dogs, like from one litter

    I don't follow this... surely (to match your comment) it would be Dog belongs_many_many Dog?

    Dog belongs_many_many Pedigrees //A dog is the parent or grandparent of an other dog so belongs in a pedigree
    Pedigree many_many Dogs //the pedigree has many dogs, Parents, grandparents, greatgrandparent


    Anyway - yes I have found this also if a Dog has a relation back to itself (either directly or indirectly) ModelAdmin fails to scaffold. Whenever I encouter this I fake the relation ship (either the has_one simply becomes an DataObjectNameID => Int or I use a text field and put a csv id list in it.

  • Stefdv
    Avatar
    Community Member
    110 Posts

    Re: Has_one but belongs_many_many Link to this post

    Swaiba,

    Tx for the reply.

    I 'solved' it in an other way.
    I want to live by the D.R.Y. rule, so i want each Dog to exists only once in my DB.

    Dog has_one Pedigree

    Dog belongs_many_many Fathers,Mothers,GrandFathers...etc

    Pedigree has_many Dogs

    Pedigree has_one Father ,Mother,GrandFather....etc

    Father many_many Dogs
    Father has_many Pedigrees
    { same goes for Mother, GrandFather etc.}

    Now i can create a pedigree by using dropdownfields for Father, Mother etc.
    There are a lot of DO's, but that's no problem ( yet)

    EDIT;
    Asked a stupid question about the filter on a Dataobject::get ...
    Sorry about that, that's kinda basic...even for me ;)

  • Stefdv
    Avatar
    Community Member
    110 Posts

    Re: Has_one but belongs_many_many Link to this post

    Back again

    help...

    In my DataBase i've got the following tables;

    dog -> ID
    father ->ID
    father_dogs -> fatherID, DogID
    pedigree ->fatherID,motherID etc.

    Now in my PedigreeAdmin (ModelAdmin) i have several DropDownTableFields where i choose the Dog that is the Father, Mother etc. (it shows the name of the Dogs, so that is good)
    In the pedigree Table the fatherID gets a value, so that's good also.
    But there it stops...the table father_dogs doesn't update...

    For my dropdowntablefield i use;

    new DropdownField('FatherID','',(DataObject::get('Dog', "Gendre = 'Male'", "PedigreeName ASC" )->toDropDownMap("ID", "PedigreeName", "Choose")));

    I don't understand why the table father_dogs doesn't update.

    In my father, mother etc DataObject i only have;

    class Father extends DataObject
    {
       static $has_many = array( 'Pedigrees' => 'Pedigree');
       static $many_many = array ('Dogs' => 'Dog');
    }

    As you can see, i don't really want to 'use' these DataObjects. I only need them as a link from my Pedigrees to my Dogs.
    I need to link each Dog to be a Father or Grandfather in the Pedigree.

    tx in advance

  • Stefdv
    Avatar
    Community Member
    110 Posts

    Re: Has_one but belongs_many_many Link to this post

    Stupid me

    I never created the link from Dog to Father or Mother...That would imply that i have, on each dog, several Tabs/fields where i have to assign the Dog to a father, mother etc....That's not an option.

    Swaiba, if your still following this post...

    Could you explain your solution with the DataObjectNameID ?

    I think i need to go this way...

    My pedigree has fields that are named ; Father, Mother, Grandfather etc.
    I need to populate these fields with Dogs, so my Father gets a DogID, Mother gets a DogID etc.

    how do i setup my Pedigree.php?
    static $db= array('Father'=> ????)

  • swaiba
    Avatar
    Forum Moderator
    1784 Posts

    Re: Has_one but belongs_many_many Link to this post

    Could you explain your solution with the DataObjectNameID ?

    sure...

    instead of...

    $has_one = array('DataObjectName' => 'DataObjectName');

    do this...

    $db = array('DataObjectNameID' => 'Int');

    it means you cannot do...

    $doDataObjectName = $do->DataObjectName();

    to get the has one, you need to do...

    $doDataObjectName = DataObject::get_by_id('DataObjectName',$do->DataObjectNameID);

    and in ModealAdmin getCMSFileds, you'll need to set it up for the dropdown field

    $dos = DataObject::get('DataObjectName');
    $map = $dos ? $dos->toDropdownMap($value,$strText) : array();
    $fields->replaceField('DataObjectNameID',new DropdownField('DataObjectNameID','DataObjectName',$map);

    same as this for a Many_many expect it stores a CSV list not an Int, except it's Text and when avoiding the relationship getters, the code is a little more complex (i.e. return a $dos from the ID list stored)

  • Stefdv
    Avatar
    Community Member
    110 Posts

    Re: Has_one but belongs_many_many Link to this post

    Okay, let's take it to the beginning please.

    I attached a screenshot ( with a little editing ) from my ModelAdmin. This is how it looks now ( Thanks Swaiba for the Literalfield explanations ).

    As you can see, this is how a Pedigree looks like. Now, i need to choose a Dog ( DataObject 'Dog' ) in every DropDown .
    The funny part is, that i actually CAN choose a Dog in every field ( i use DataObject::get('Dog') for every Dropdown, so that makes sence.)

    But it never saves it to any table....

    I've made a DO for every subject.

    Father has_one Dog
    Mother has_one Dog etc.

    Dog has_many Fathers etc....

    Pedigree has_one Father etc.

    But then i have to manage all these DO seperate, when all i want is some kind of 'link' from Pedigree->Father Field-> Dog

    So i guess my real question ( for now ;) ) is...;

    How do i populate the different DropDownFields with the same DO , and save it to 'what table' ?

    If anyone can help out...well...THANK U

    Attached Files
  • Stefdv
    Avatar
    Community Member
    110 Posts

    Re: Has_one but belongs_many_many Link to this post

    This topic can be marked as Solved.

    I leave it here in case someone else wants to make a pedigree.

    I want to thank everybody on the forum ( and especially Swaiba for the explanation about Literalfields and thinking with me ), because i used a lot of code from the forum.

    I started with a new approach.

    Each Dog only has to have a Father and a Mother. BUT...the Father and Mother are in fact 'Dog' DataObjects.

    So i made a verry simple DataObject for the Father and Mother.

       class Father extends DataObject
    {
       static $has_one= array   ('MyDog'          =>    'Dog');
    }

    Same for the Mother.

    For the Dog i have;

    stclass Dog extends DataObject
    {
       static $db = array(   'Name'    =>    'Varchar', //and a lot more !

    static $has_one = array('Image'=> 'Image',
                    'MyFather'   =>   'Father',
                    'MyMother'   =>   'Mother'
                         );

    Now the fun part is that i'm not using the Father and Mother DataObjects at all. Somehow i need to create these to prevent an error.
    In fact all i need is the Dog.MyFatherID and Dog.MyMotherID.

    I created a Dropdownfield for both Father and Mother in my Dog DO.

          //Father
           $mySet1 = DataObject::get('Dog', "Gendre = 'Male'", "PedigreeName ASC");
          $map1 = $mySet1 ? $mySet1->toDropDownMap('ID', 'PedigreeName', 'Choose') : '';
          $fields->addFieldToTab("Root.Main", new DropdownField('MyFatherID', 'Father', $map1 ));
       
          //Mother
              $mySet1 = DataObject::get('Dog', "Gendre = 'FeMale'", "PedigreeName ASC");
          $map1 = $mySet1 ? $mySet1->toDropDownMap('ID', 'PedigreeName', 'Choose') : '';
          $fields->addFieldToTab("Root.Main", new DropdownField('MyMotherID', 'Mother', $map1 ));

    So i'm 'injecting' the FatherID and MotherID fields with a DogID.

    Now i can get my Father and Mother with a function on my Dog DO. I get the Dog with the ID that was put in my MyFatherID.

    function getMyDad() {
       $father = dataObject::get_by_id('Dog', $this->MyFatherID);
       return $father;

    }

    function getMyMom() {
       $mother = dataObject::get_by_id('Dog', $this->MyMotherID);
       return $mother;
    }

    In my template i can now buid a pedigree by putting a control MyDad inside a control MyDad inside a control MyDad etc.
    ps. I could use $myDad.MyDad.Mydad etc. but i want to use the $Link to show a virtual page for every dog.

    Well anyway ...i'm verry verry happy.

    Thank u SlverStripe.

    2004 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.