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.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Data Model Questions /

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

Stuck on has_one, has_many, and many_many


Go to End


3 Posts   1490 Views

Avatar
BuckeyeSam

Community Member, 7 Posts

5 June 2015 at 3:24pm

Edited: 05/06/2015 3:31pm

I have watched lesson 7 - lesson 10 videos and have read all the articles on this page: http://docs.silverstripe.org/en/3.1/developer_guides/model/, been all up in the API and have googled these forums for hours. I am really stuck trying to apply what I learned though. Here is what I'm trying to do. I want to expand on the Article Holder & Article Page concept. I am trying to make another page that is a Master Article Holder and my site tree will be organized as such:

HomePage
   |
   | _ MasterArticleHolderOne
   |      |
   |      | _ ArticleHolderA
   |      |      |
   |      |      | _ ArticlePageA1
   |      |      |
   |      |      | _ ArticlePageA2
   |      |      |          
   |      |      | _ ArticlePageA3
   |      |
   |      |
   |      | _ ArticleHolderB
   |      |      |
   |      |      | _ ArticlePageB1
   |      |      |
   |      |      | _ ArticlePageB2
   |      |      |          
   |      |      | _ ArticlePageB3
   |      |
   |      |
   |      | _ ArticleHolderB
   |             |
   |             | _ ArticlePageB1
   |             |
   |             | _ ArticlePageB2
   |             |          
   |             | _ ArticlePageB3
   |       
   | _ MasterArticleHolderTwo

What I would like the MasterArticleHolder page to do is this: There will be an option in the CMS for the MasterArticleHolder page to select any existing ArticleHolder pages (meaning that even MasterArticleHolderTwo from above could display articles from ArticleHolderA or B or C) and the MasterArticleHolder page will then display all the articles that are children of the selected ArticleHolder pages. These articles need to be sorted by PublicationDate; not grouped by what holder they belong to.

Here is the code that I've written so far. The ArticlePage and the ArticleHolder work perfectly. It's the MasterArticleHolder that I'm struggling with (though I did manage to at least create checkboxes appear in the CMS for all existing ArticleHolder page, don't know if it will actually function once everything else is written):

ArticlePage

class ArticlePage extends Page {
    
	private static $db = array(
        'PublicationDate' => 'Date',
    );

    public function getCMSFields() {
        $fields = parent::getCMSFields();

        $fields->addFieldToTab('Root.Main', DateField::create('PublicationDate','Publication Date')->setConfig('showcalendar', true));
        
        return $fields;
    }
}

ArticleHolder

class ArticleHolder_Controller extends Page_Controller {

    public function LatestArticles() {
        return ArticlePage::get()
            ->filter('PublicationDate:LessThanOrEqual', SS_Datetime::now())
            ->sort('PublicationDate', 'DESC');
    }
}

MasterArticleHolder

class MasterArticleHolder extends Page {

    private static $many_many = array (
        'Categories' => 'ArticleHolder'
    );

    public function getCMSFields() {
        $fields = parent::getCMSFields();
        
        $fields->addFieldToTab('Root.Main', CheckboxSetField::create(
            'Categories',
            'Articles to Display',
            ArticleHolder::get()->map('ID','MenuTitle')
        ));
        
        return $fields;
    }

}
class MasterArticleHolder_Controller extends Page_Controller {

    public function LatestArticles() {
        return ArticlePage::get()
            ->filter(array('PublicationDate:LessThanOrEqual' => SS_Datetime::now()))
            ->sort('PublicationDate', 'DESC')
    }
}

Seems to me that there could be the following relations but I just don't know what is needed, if any
- ArticlePage is a has_one with ArticleHolder
- ArticleHolder is a has_many with ArticlePage
- ArticleHolder is a many_many with MasterArticleHolder (Don't really know which one is the belongs_many_many but I'd guess Article Holder)

The following relation may also apply but they seem less likely to me
- ArticlePage is a many_many with MasterArticleHolder

Now I know normally the the has_one, has_many, and many_many apply to objects that extend DataObject but I figured that since page in a round-about way extends DataObject that these relationships may still apply, but I could be completely wrong and really overthinking things.

Hopefully I explained myself well enough for me to get help, but not too much to overwhelm everyone. I appreciate the feedback!

Avatar
Pyromanik

Community Member, 419 Posts

5 June 2015 at 10:34pm

I see this was crossposted to stackoverflow, and already has an answer there.
So I'll just post this so anyone looking here can find an answer there: http://stackoverflow.com/questions/30658410/using-has-one-has-many-and-many-many-in-controller-to-filter-queries

Avatar
BuckeyeSam

Community Member, 7 Posts

6 June 2015 at 9:52am

The answer at Stack Overflow solved my problem. See the link in the post above for the answer.