Laravel 4 Eloquent: многие ко многим с условиями при соединении таблицы

Я пытаюсь переписать некоторую логику для базы данных, которая ранее использовалась с Codeigniter. Конструкция такова, что некоторые условия соединения «многие ко многим» хранятся в таблице соединений следующим образом:

Table user
  - user_id
  ...

Table avatars
  - user_id
  - image_id
  - uploaded_timestamp
  - deleted_timestamp

Table images
  - image_id
  ...

В этом случае я хочу получить все изображения, связанные с пользователем, через таблицу аватаров, упорядоченные по времени загрузки по убыванию и не включая удаленные аватары (deleted_timestamp не нуль).

Я обнаружил, что использование hasMany в Eloquent не допускает условий для присоединяемой таблицы. Каков самый чистый способ добиться этого эффекта, или мне нужно прибегнуть к созданию полного запроса так, как я привык к классу активной записи Codeigniter?

Примечание. Я нашел этот ответ, в котором предлагается использовать ->hasMany(..)->with('another_column_from_pivot_table'), но, похоже, он работает только с Реализация Eloquent в Laravel 3. Кажется, ->with теперь только для загрузки eagar.


person epocsquadron    schedule 19.02.2013    source источник


Ответы (1)


hasMany() предназначен для отношений "один ко многим". Многие ко многим ожидают belongsToMany() — это оператор, который привязывается к промежуточной ("сводной") таблице.

Я не пробовал, но могу поверить, что ownToMany() не будет работать с оператором where(). Я знаю, что hasMany() прекрасно работает с where().

Что вам может понадобиться сделать, так это создать третий класс модели:

(ВНИМАНИЕ: непроверенный код)

class User extends Eloquent {
   public avatars() {
      return $this->hasMany('Avatar')
                  ->where ('deleted_timestamp',0)
                  ->orderBy('uploaded_timestamp','desc');
   }
}

class Avatar extends Eloquent {
  public image() {
    return $this->belongsTo('Image');
  }
}

class Image extends Eloquent {
}

Вы бы получили доступ к своим изображениям как...

$avatars = User::find($user_id)->avatars();
foreach ($avatars as $avatar) {
   echo '<img src="$avatar->image->url">';
}
person J.T. Grimes    schedule 19.02.2013
comment
Спасибо. Я также обнаружил, что вы можете использовать ->withPivot('column_name') для получения значений столбцов сводной таблицы, возвращаемых вместе с коллекцией из containsToMany. Но, как вы указываете, это по-прежнему не дает мне возможности добавить порядок и фильтровать коллекцию. Ваш подход будет работать, наряду с использованием foreach в коллекции и ручным извлечением и упорядочением, но ваш вариант более идеален. Спасибо! - person epocsquadron; 20.02.2013