Mathias Lund
Mathias Lund

Reputation: 772

Doctrine can't find method in symfony

I've this issue that keeps bugging me. I'm trying to join a couple of tables with DQL in symfony, but it keeps throwing an exception saying:

"Method "rankings" for object "AppBundle\Entity\Keyword" does not exist in @App/default/index.html.twig at line 37"

This is my DQL:

$query = $em->createQuery(
        'SELECT e,k,r
         FROM AppBundle:Keyword k
         JOIN k.company c
         LEFT JOIN k.entry e
         LEFT JOIN e.rankings r
         WHERE c.user = :id
         ORDER BY k.name ASC'
    )->setParameter('id',$user_id);


$keywords = $query->getResult();

I think I know what the problem is - but I don't know how to solve it. My keyword entity looks like this:

AppBundle\Entity\Keyword:
type: entity
table: null
id:
    id:
        type: integer
        id: true
        generator:
            strategy: AUTO
fields:
    name:
        type: string
        length: 255

manyToOne:
    company:
        targetEntity: AppBundle\Entity\Company

oneToMany:
     entry:
        targetEntity: AppBundle\Entity\Entry
        mappedBy: keyword


lifecycleCallbacks: {  }

Please note that there is no direct join relation between the ranking entity and the keyword entity - that relation is in the entry entity which is the link between keyword entity and ranking entity:

AppBundle\Entity\Entry:
type: entity
table: null
id:
    id:
        type: integer
        id: true
        generator:
            strategy: AUTO
fields:
    path:
        type: string
        length: 255

manyToOne:
     keyword:
        targetEntity: AppBundle\Entity\Keyword

oneToMany:
     rankings:
        targetEntity: AppBundle\Entity\Ranking
        mappedBy: entry

lifecycleCallbacks: {  }

Here is the ranking entity:

AppBundle\Entity\Ranking:
type: entity
table: null
id:
    id:
        type: integer
        id: true
        generator:
            strategy: AUTO
fields:
    position:
        type: integer
    visits:
        type: integer
        nullable: TRUE
    bounces:
        type: integer
        nullable: TRUE
    date:
        type: datetime


manyToOne:
    entry:
        targetEntity: AppBundle\Entity\Entry

lifecycleCallbacks: {  }

I appreciate all kinds of help! :)

EDIT

Ok, so if I pass the DQL written above to the twig template: how do I retrieve the ranking if it's a manyToOne relation? If I do like this:

   {% for ranking in keyword.entry.rankings %}
      <td>{{ ranking.id }}</td>
   {% endfor %}

it gives me Method "rankings" for object "Doctrine\ORM\PersistentCollection" does not exist in @App/default/index.html.twig at line 37

Upvotes: 3

Views: 724

Answers (2)

Rvanlaak
Rvanlaak

Reputation: 3085

If you want the ranking, you should retrieve it via the Entry.

You do not need to write DQL for that, just use the object that the $em will return to you:

$ranking = $em->find('AppBundle:Keyword', $keywordId)->getEntry()->getRanking();

Do you have defined all Entity classes already?

http://symfony.com/doc/current/book/doctrine.html

EDIT

If you get an error that you try to access a property of a collection, that means that you don't use a OneToOne but a OneToMany relation. You should loop over that collection before you access the Ranking. Each Entry element has a Ranking, it isn't the collection that has the ranking.

Upvotes: 0

DonCallisto
DonCallisto

Reputation: 29912

Modify your twig as I'll show you here

{% for entry in keyword.entry %}
  {% for ranking in entry.rankings %}
    <td>{{ ranking.id }}</td>
  {% endfor %}
{% endfor %}

because entry is not a single entity but a collection of entities

You have also written into your entity mapping file

AppBundle\Entity\Keyword:
[...]
oneToMany:
     entry:
        targetEntity: AppBundle\Entity\Entry
        mappedBy: keyword

for that reason, even if your query will hydrate only one record from your relationship, the result will be a collection (of some kind, in this case, a PersistenCollection)

Upvotes: 1

Related Questions