简体   繁体   中英

Symfony | How to access the custom methods from the respository in a controller?

I'm setting up a checklist to practice building web applications using Symfony. It works by inputting a string into a form and pressing a submit button. The input is stored in the database.

I want to return the input stored in the database to the web page.

Currently, the input is stored in the database and I have written a function for a DQL query in my repository.

My issue is that I cannot access the method I have created in my controller.

    /**
     * @return Checklist[]
     */
    public function getAllItemsForChecklist(): array
    {
        $qb = $this->createQueryBuilder('c')
            ->select('item')
            ->from('checklist', 'x') 
            ->getQuery()
        ;

        return $qb->execute();
    }

$items = $this->getDoctrine()
    ->getRepository(ChecklistRepository::class)
    ->getAllItemsForChecklist()
;

According to the Symfony documentation at https://symfony.com/doc/master/doctrine.html#querying-for-objects-the-repository this should work. However, the method "getAllItemsForChecklist() is not found. The following message is given on my IDE:

Method 'getAllItemsForChecklist' not found in \\Doctrine\\Common\\Persistence\\ObjectRepository

I am unsure why it is not reading the repository class I specified.

If anyone knows how to solve this issue so it will find the method I made in my repository that would be greatly appreciated.

Also if any extra information is needed, please tell me I am happy to give more information.

Regards,

Steve

Welcome to StackOverflow!

First, when you call getRepository() you must pass the entity class, not the repository itself, so it would be like this:

$this->getDoctrine()->getRepository(Checklist::class);

Even if you do that, your IDE won't know that the method exists. Your IDE is actually wrong, the method does indeed exist, your IDE just has no way to know what object was returned from getRepository() call.

How to avoid that? Choose one of these solutions (all of them work in PhpStorm, option 1 should work everywhere, option 2 is likely to work in all modern IDEs, I don't know about option 3 support in other IDEs):

Option 1: Inject it as a service

public function myControllerRoute(ChecklistRepository $checklistRepository) {
    // now your IDE knows what methods are inside the $checklistRepository
    $items = $checklistRepository->getAllItemsForChecklist();
}

Option 2: Typehint it to the IDE (and other developers)

public function myControllerRoute() {
    /** @var ChecklistRepository $checklistRepository */
    $checklistRepository = $this->getDoctrine()->getRepository(Checklist::class);

    // after the typehint the IDE knows what type it is
    $items = $checklistRepository->getAllItemsForChecklist();
}

Option 3: use asserts

public function myControllerRoute() {
    $checklistRepository = $this->getDoctrine()->getRepository(Checklist::class);
    assert($checklistRepository instanceof ChecklistRepository);

    // after the assert the IDE knows what type it is
    $items = $checklistRepository->getAllItemsForChecklist();
}

Options 2 and 3 are pretty much the same, but option 3 has an added bonus that on development machine it will throw exception if the $checklistRepository is not instance of ChecklistRepository , on production environment assert() calls are ignored and don't slow the execution at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM