2014-09-30 6 views
13

Я новичок в Laravel и Eloquent, поэтому извините меня, если это совершенно глупый вопрос. Я смотрел, как создать модель как на документации here, так и на другом учебнике here (в разделе «Создание моделей с использованием Eloquent ORM section»), и я заметил, что фактические поля таблицы никогда не упоминаются, если нет что-то конкретное о них (например, наличие отношений с другой таблицей или не требующее массового присвоения или если они должны быть скрыты от выхода JSON и т. д.)Поля в Laravel Eloquent модели

Эти поля опущены специально, а PHP просто добавляет их, когда он выполняет запрос с использованием PDO с включенным FETCH_OBJ? Если да, то почему мы явно не помещаем поля в модель? Разве это не помогает нам узнать, какие поля у нас есть, а также IDE, такие как PHPStorm, чтобы открыть правильные поля автозаполнения?

Если они действительно необходимы, какой уровень доступа им нужен?

Спасибо.

ответ

16

Имена колонок (полей) не требуются в моделях «Красноречивого». Как вы указали, необходимо только определить функции, которые определяют отношения, которые модель имеет с другими.

Нет необходимости включать их по причине, о которой вы говорили (Laravel делает select *, а затем добавляет все возвращенные строки объекту модели в качестве общедоступных свойств). Это процесс, называемый гидратацией, и вы можете точно видеть, что происходит, врываясь в источник Laravel. Вот краткое описание того, что происходит:

  1. Вы звоните (например), Users::find(123);
  2. Illuminate\Database\Eloquent\Model::find() звонки Illuminate\Database\Eloquent\Builder::find()
  3. find() строит SELECT * FROM users WHERE id = 123 запрос и возвращает первый результат, вызвав Illuminate\Database\Eloquent\Builder::first()
  4. first() добавляет LIMIT 1 по телефону Illuminate\Database\Query\Builder::take()
  5. Затем first() устанавливает столбцы в r etrieved (*) по телефону Illuminate\Database\Eloquent\Builder::get().
  6. get() возвращает Illuminate\Database\Eloquent\Collection с помощью возвращаемого значения Illuminate\Database\Eloquent\Builder::getModels()
  7. getModels() фактически выполняет запрос, а затем вызывает Illuminate\Database\Eloquent\Model::newFromBuilder() для каждой строки возвращается
  8. newFromBuilder() создает новый экземпляр модели и наборы столбцов (полей) по телефону Illuminate\Database\Eloquent\Model::setRawAttributes()

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

Вы хорошо знаете, что знание полей заранее может быть полезно для автозаполнения. Из-за природы setRawAttributes() вполне нормально объявлять все имена (поля) в вашей модели (просто убедитесь, что они общедоступны). Однако конвенция (и для вас здравомыслие) заключается в том, чтобы опустить их. Такие декларации должны быть оставлены до migration files.

После дополнительного изучения источника, это не ok, чтобы объявить поля заранее. Это связано с тем, что фактические значения атрибутов хранятся в свойстве $attributes, а затем доступны по магическому методу __get(). Проблема заключается в том, что, предварительно определив свойства, вы предотвратите вызов __get() при доступе к полям. Поэтому это не вариант.

Однако, есть ways to hint to editors (like PhpStorm) about the existence of properties without explicitly defining them.

+1

Спасибо за подробный ответ. Жаль, что я не могу использовать его так же, как PDO 'fetchObject()', где я мог бы указать имя класса, и он увлажняет экземпляр моего конкретного класса. Я фактически использую PhpStorm, и кажется, что подсказки, использующие теги phpdoc, работают, поэтому это хороший способ обхода подходящей поддержки IDE. – jbx

+0

Если вам действительно нужна эта функциональность, вы можете подклассифицировать класс «Eloquent», который на самом деле «Illuminate \ Database \ Eloquent \ Model», (посмотрите в 'app/config/app.php' для массива псевдонимов и убедитесь, что задайте псевдоним «Eloquent» правильному FQN для вашего подкласса Eloquent) и определите 'setRawAttributes()', чтобы вести себя так, но это, вероятно, будет более сложным, просто используя теги phpdoc. –

+1

Да, это станет чрезмерно сложным и выходит за рамки того, чего я пытаюсь достичь. Я просто хочу, чтобы вещи были чистыми и поддерживаемыми. Отклонение слишком большого количества от стандартного способа может также поставить меня в ситуацию, когда я не буду искать решения или задавать вопросы здесь. Теги phpdoc кажутся прекрасными, они также полезны для указания того, какие волшебные поля у модели есть, если открыть ее через менее интеллектуальный редактор, например Notepad ++ или Vi. Спасибо за понимание! – jbx

Смежные вопросы