Laravel: Eloquent all () не возвращает массив объектов

Я пытаюсь построить простую систему форумов.

У меня есть модель под названием Category.php, в которой я определяю таблицу и расширяю Eloquent.

У меня есть CategoryController.php, который является находчивым контроллером, в методе index () я делаю:

$categories = Category::all();

Что, как я полагаю, должно возвращать массив объектов. Это отлично сработало в другом моем проекте.

Однако, когда я пытаюсь выполнить это через foreach, ничего не отображается. Я попытался переименовать контроллер и модель в ForumController и Form соответственно, и это сразу сработало.

Любые идеи? Возможно, название категории было зарезервировано Laravel и отменяет мою желаемую функциональность?

CategoryController.php:

<?php

class CategoryController extends \BaseController {

protected $layout = 'master';

/**
 * Display a listing of the resource.
 *
 * @return Response
 */
public function index()
{
    //
    $categories = Category::all();
    $this->layout->content = View::make('category.index', array('categories' => $categories));
}

Category.php (модель):

<?php

class Category extends Eloquent {

/**
 * The database table used by the model.
 *
 * @var string
 */
protected $table = 'categories';

}

Category / index.blade.php (просмотр):

@section('content')
<ul>
@foreach ($categories as $category)
    <li><a href="/category/{{ $category->slug }}">{{ $category->name }}</a></li>
@endforeach
</ul>
@stop

Моя база данных настроена правильно. Когда я запускаю $ category = Category :: find (1); он правильно возвращает категорию с идентификатором 1, которую я могу использовать как объект.


person Karl    schedule 16.02.2014    source источник
comment
Такое ощущение, что вы даже не пытались foreach обработать коллекцию, потому что, если бы вы это сделали, вы бы обнаружили, что это работает.   -  person alexrussell    schedule 16.02.2014
comment
Ну нет, потому что я не знал, как коллекции работают в Laravel. Поэтому я спросил здесь, как это оправдывает голосование против?   -  person Karl    schedule 16.02.2014
comment
Извините, что вы так думаете. Голос против был вызван тем, что, честно говоря, я не думаю, что этот вопрос приносит пользу сообществу SO. Сам вопрос ошибочен в том, что вы говорите, что я не могу создать коллекцию, хотя на самом деле это возможно, поэтому это может ввести в заблуждение других людей в сети. (Источник аргументов в пользу отрицательного голосования на основе вышеизложенного: stackoverflow.com/help/privileges/vote-down)   -  person alexrussell    schedule 16.02.2014
comment
Ну, не совсем так, так как я пытался запустить foreach, но выхода не было, поэтому я написал здесь с просьбой о совете. Затем я изменил имя с категории на форум, и все сработало нормально, как вы можете понять по комментариям к другим ответам. Это заставляет меня думать, что Категория зарезервирована или что-то в этом роде. Поскольку это не сработало, как ожидалось.   -  person Karl    schedule 16.02.2014
comment
В этом случае, возможно, стоит отредактировать свой вопрос, чтобы показать код, в котором вы пытаетесь запустить foreach (а не dd, который не совсем работает так же, как он может проверять частные и защищенные свойства объектов, а не волшебные), чтобы люди могли увидеть, есть ли проблема с вашим реальным кодом foreaching.   -  person alexrussell    schedule 16.02.2014
comment
Справедливо, но я все еще не думаю, что это оправдывает голосование против. Однако я считаю, что это проблема с использованием категории в качестве имени модели и контроллера, поскольку это единственное, что отличает мои проекты.   -  person Karl    schedule 16.02.2014
comment
Я не думаю, что это связано с использованием Category в качестве названия модели - скажем так, по крайней мере 25% приложений Laravel, вероятно, будут иметь модель Category, но, возможно, из-за вашего кода в более широком контексте. Хорошо, что вы отредактировали свое сообщение, но вы все еще не указываете точный код, который не работает в foreach - нам было бы действительно полезно увидеть этот код, если там все еще есть что-то странное. Я знаю, что вы сказали, что замена его на другую модель работает нормально, но, тем не менее, почему бы просто не предоставить ее в любом случае?   -  person alexrussell    schedule 16.02.2014
comment
Кроме того, к вашему сведению, я с радостью отзову свой отрицательный голос (при условии, что SO позволяет мне), когда вопрос будет прояснен в достаточной степени. Я не пытаюсь заставить вас требовать выкуп здесь, на голосование против - вы можете делать все, что хотите, со своим вопросом - просто объясняя мое личное мнение по этим вопросам.   -  person alexrussell    schedule 16.02.2014
comment
Теперь я снова отредактировал всю информацию, которая вам может понадобиться, включая представление, на этот раз, где я фактически запускаю foreach.   -  person Karl    schedule 16.02.2014
comment
Я действительно не хочу делать здесь много комментариев, но нам нужно больше информации. Как именно это терпит неудачу? Ничего не печатается (т. Е. foreach ($categories), похоже, не получает даже одной итерации) или HTML-код печатается, но поля на каждом $category не выводятся? Кроме того, у вас нигде нет кода типа View::share('categories', $someValue)? Возможно, это могло быть причиной зарезервированного имени переменной.   -  person alexrussell    schedule 17.02.2014


Ответы (2)


Вы можете перебирать Category::all();. Класс Laravels Collection реализует следующие интерфейсы:

ArrayAccess, ArrayableInterface, Countable, IteratorAggregate, JsonableInterface

Что значит:

foreach(Category::all() as $category) { 
    var_dump($category);
}

Будет работать, возвращаемый Eloquent\Collection расширяет класс Support\Collection, реализующий вышеуказанные интерфейсы.

Взгляните на класс Support\Collection в Illuminate.

person SamV    schedule 16.02.2014

Вы правы, при возврате нескольких результатов Eloquent возвращает Collection (что является довольно распространенной практикой среди фреймворков).

Вы можете преобразовать Collection в другие форматы, используя такие методы, как toArray() или toJson(); но вы также можете перебирать count() результатов, используя такие методы, как fetch(), или получать определенные записи, используя get()

ИЗМЕНИТЬ

Хотя вы не можете выполнять итерацию непосредственно по Collection, вы можете преобразовать его в повторяемую структуру с помощью метода getIterator(), который возвращает SPL объект ArrayIterator

person Mark Baker    schedule 16.02.2014
comment
Ах да, в этом есть смысл. Единственное, что меня озадачивает, это то, что в другом проекте я проделал то же самое, и я могу использовать foreach, чтобы делать все, что хочу, без необходимости использовать такой метод, как toArray (). Мне очень любопытно, почему и что может вызвать эту разницу. - person Karl; 16.02.2014
comment
Я только что скопировал модель и контроллер, изменил имена для Category на Forum, и все заработало нормально, вызвав $ forum = Forum :: all () и запустив foreach для переменной $ forum. Так может быть, Laravel каким-то образом резервирует название категории? Я не совсем уверен. - person Karl; 16.02.2014