0

I made myself a plugin for loading related content with beforeFind(), so you could say that ContentPage/10 is similar to ConentNews/10 and Gallery/5.

My table related_contents looks like:

id                  int(11)
source_table_name   varchar(255)
target_table_name   varchar(255)
source_table_id     int(11)
target_table_id     int(11)

My code in behavior:

public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary) {
  $attachedTables = self::getAttachedTables(); //Array of ORM models which has this behavior
  foreach ($attachedTables as $attachedTable) {
    $options = [
      'through'    => 'RelatedContents',
      'bindingKey' => 'RelatedContents.source_table_id',
      'foreignKey' => 'RelatedContents.target_table_id',
      'conditions' => [
        'RelatedContents.source_table_name' => $this->_table->table(),
        'target_table_name' => $attachedTable->table(),
      ]
    ];
    $this->_table->belongsToMany($attachedTable->alias(), $options);
  }
}

Now, when i try to find() in my model, zero related entities are found with no error. What am i doing wrong?

Oops D'oh
  • 941
  • 1
  • 15
  • 34
Aiphee
  • 8,904
  • 3
  • 18
  • 16
  • I don't think `beforeFilter` is the right place to put your code. Try `initialize` instead – arilia Dec 02 '15 at 12:44
  • I tried, it triggers recursion because of the getAttachedTables() method. But i dont think it should make a difference, i tried to put hasMany in beforeFind and it works. – Aiphee Dec 02 '15 at 13:29

1 Answers1

2

If calling your getAttachedTables() method on intialization time causes recursion, then there might be something that needs to be fixed. Reassociating on every find doesn't seem like an overly good idea, unless you really need to do so because the associations have changed/need to change, or have been removed.

That being said, your problem most probably is the missing targetForeignKey option, the bindingKey option that you are using is not available for BelongsToMany associations! Also note that the foreign keys need to be defined without aliases!

Also you're also missing an alias in the conditions, but that shouldn't have anything to do with the problem that no associations are being fetched.

So, foreignKey should be set to the FK column in the current model, and targetForeignKey to the FK column of the target model, like

$options = [
    // ...
    'foreignKey'       => 'source_table_id',
    'targetForeignKey' => 'target_table_id',
    // ...
];

See also

ndm
  • 59,784
  • 9
  • 71
  • 110
  • You are golden, thank you. I kept changing code and reading documentation yet i read it badly. Is there really any diffrence if association is added in beforeFind over initialize? – Aiphee Dec 03 '15 at 07:42
  • 1
    @Aiphee The difference is that with this being done in `beforeFind`, associations are being set again for every single find call, while with `initialize` it should happen only once per table class instance. – ndm Dec 04 '15 at 15:41
  • So when i simply show index page, there should not be much difference but it could make a difference on chained searches or subqueries right? – Aiphee Dec 06 '15 at 09:39
  • 1
    @Aiphee Depends on what you're doing in your index action. You can always log the invocation of your code to see when it is being executed. – ndm Dec 07 '15 at 16:39