Silverstripe3 relation

<%- if @topic_view.topic.tags.present? %>
<%= t 'js.tagging.tags' %>: <%- @topic_view.topic.tags.each do |t| %> <%= t %> <%- end %>
<% end %>

Silverstripe Version: Silverstripe3

Question:

How to get Prize Categories table?

my prize class: 
class Prize extends DataObjectAsPage {
    private static $db = array(
        'Points' => 'Int',
        'UseBalance' => 'Boolean(1)',
        'Balance' => 'Int',
        'Like' => 'Int',
        'PrizeStatus' => 'Int',
        'SortOrder' => 'Int'
    );
    private static $has_one = array(
        'Parent' => 'PrizeHolder',
        'Photo' => 'Image'
    );

    private static $many_many = array(
        'Levels' => 'MemberLevel',
        'PrizeCategories' => 'PrizeCategory'
        // 'PrizeCategories' => PrizeCategory::class,
    );
}
Prize categories class
class PrizeCategory extends DataObject {

    private static $db = array (
        'Title' => 'text',
    );

    private static $belongs_many_many = array(
			'Prizes' => 'Prize'
      // 'Prizes' => Prize::class
		);

}

class Prize_Category_Controller extends Page_Controller {

}

Can you be a bit more detailed with your question? What is it you need to do?

If you just want to get the categories for a prize, then you can access the relation directly:

$categories = $prize->PrizeCategories();

I need to get Categories attached to Prizes. If i use this, i have error: the method ‘prizecategories’ does not exist on ‘HasManyList’, or the method is not public. I use $categories = $this->Prizes()->PrizeCategories()

Where are you using this code?
If you are able to provide a slightly more complete example, it should be easier to track down the problem.

I have Prize.php:
class Prize extends DataObjectAsPage {
private static $db = array(
‘Points’ => ‘Int’,
‘UseBalance’ => ‘Boolean(1)’,
‘Balance’ => ‘Int’,
‘Like’ => ‘Int’,
‘PrizeStatus’ => ‘Int’,
‘SortOrder’ => ‘Int’
);
private static $has_one = array(
‘Parent’ => ‘PrizeHolder’,
‘Photo’ => ‘Image’
);

private static $many_many = array(
    'Levels' => 'MemberLevel',
    'PrizeCategories' => 'PrizeCategory'
);

private static $many_many_extraFields = [
    'PrizeCategories' => [
      'ID' => 'Int'
    ]
];

private static $listing_page_class = ‘PrizeHolder’;
private static $item_class = ‘Prize’;
private static $singular_name = ‘Prize’;
private static $plural_name = ‘Prizes’;
private static $default_sort = ‘SortOrder ASC’;
public function getCMSFields() {
$fields = parent::getCMSFields();
//$fields->removeByName(‘ParentID’);
$fields->removeByName(‘PhotoID’);
$fields->removeByName(‘SortOrder’);
$fields->removeByName(‘Levels’);
$fields->removeByName(‘Active’);

    $title = TextField::create('Title', _t('CMSMAIN.Title', 'Title'));
    $content = HtmlEditorField::create('Content', _t('CMSMAIN.Content', 'Content'));
    $like = TextField::create('Like', _t('CMSMAIN.Like', 'Like'));
    $status = DropdownField::create('PrizeStatus', _t('CMSMAIN.Status', 'Status'), self::$_status);
    $balance = TextField::create('Balance', _t('CMSMAIN.Balance', 'Balance'));
    $balance->displayIf("UseBalance")->isEqualTo(1);

    $points = NumericField::create('Points', _t('CMSMAIN.Points', 'Points'));
    $photo = UploadField::create('Photo', _t('CMSMAIN.Photo', 'Photo'))
        ->setFolderName('Uploads/Prize')
        ->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));
    $use_balance = OptionsetField::create("UseBalance", _t("CMSMAIN.UseBalance", "UseBalance"), array(
        0 => _t('CMSMAIN.NO', 'No'),
        1 => _t('CMSMAIN.YES', 'Yes')
    ), 1);
    $levels = CheckboxSetField::create('Levels', _t('CMSMAIN.Levels', 'Levels'),
        MemberLevel::get()->map('ID', 'Title')->toArray()
    );

    $fields->addFieldsToTab('Root.Main', array(
        $content
    ));

    $fields->addFieldsToTab('Root.Main', array(
        $title,
        $photo,
        $points,
    ), 'Content');

    $fields->addFieldsToTab('Root.Settings', array(
        $use_balance,
        $levels,
        $balance,
        $status,
        $like
    ));

      $config = GridFieldConfig_RelationEditor::create();
			// Set the names and data for our gridfield columns
			$config->getComponentByType('GridFieldDataColumns')->setDisplayFields(array(
				'Title' => 'Title',
				'Prize.Title'=> 'Prize' // Retrieve from a has-one relationship
			));
      $PrizeCategoriesField = new GridField(
				'PrizeCategories',
				'PrizeCategories',
				$this->PrizeCategories(),
				GridFieldConfig_RelationEditor::create()
		  );
		$fields->addFieldToTab('Root.PrizeCategories', $PrizeCategoriesField);

    return $fields;
}

}

Then i have Prize Category:
class PrizeCategory extends DataObject {

private static $db = array (
    'Title' => 'text',
);

private static $belongs_many_many = array(
		'Prizes' => 'Prize'
  // 'Prizes' => Prize::class
	);

}

class Prize_Category_Controller extends Page_Controller {

}
And I do everyting i PrizeHolder:
class PrizeHolder extends DataObjectAsPageHolder {
private static $has_many = array(
‘Prizes’ => ‘Prize’,
‘PrizeCategories’ => ‘PrizeCategory’,
‘Products’ => ‘Product’,
‘Orders’ => ‘PrizeOrder’,
‘Registrations’ => ‘ProductRegistration’
);

}
class PrizeHolder_Controller extends DataObjectAsPageHolder_Controller {
public function Items($limit = null){
$category = $this->request->getVar(‘category’);

    $sort = $this->request->getVar('sort');
    $search = $this->request->getVar('search');

    $member_level = Member::currentUser()->Level()->Level;

    $filter = array();
    $filter['PrizeStatus'] = array(1,2);
    $filter['Levels.Level'] = $member_level;


    if($search){
        $filter['Title:PartialMatch'] = $search;
    }

    $items = $this->Prizes()->filter($filter);


    // $prizes = Prize::PrizeCategories()->get();
    // Debug::dump($prizes);
    if($sort == 'my'){
        $member = Member::currentUser();
        $points = $member->ActivePoints;
        $items = $items->exclude(array(
            'Points:GreaterThan' => $points
        ));
    }

    if($sort == 'exp'){
        $items = $items->sort('Points', 'DESC');
    }

    if($sort == 'cheap'){
        $items = $items->sort('Points', 'ASC');
    }

    if($category != null){
        // Debug::dump($this->Prizes()->PrizeCategories()->get();
        // TODO: You need to extract data from relations -> check where PrizeCategoryID is $category (1,2,3 etc.) then show the products
        // TODO: Check what shit is Column 'ParentID' in where clause is ambiguous
        // TODO: Filter by relationship table
        // $items = $items->filter('PrizeCategories.PrizeCategoryID:ExactMatch', $category);
        // $items = $items->filter('Prize.Prize_PrizeCategoryID:ExactMatch', $category);
        // $prizeCategories = Prize::currentUser()->PrizeCategories()->PrizeCategoryID;
        $items = Prize::get();

        Debug::show($this->Prizes()->PrizeCategories());

        // echo $this->Prizes()->Title;
        // $filter = array();
        // $filterCategories['PrizeCategories'] = $prizeCategories;
        // Debug::dump($filterCategories)
    }

    $limit = $this->ItemsPerPage ? $this->ItemsPerPage : 10;

    $items = new PaginatedList($items, $this->request);
    $items->setPageLength($limit);

    $this->extend('updateItems', $items);

    return $items;
}

}

I need a logic for category != null