Более дружественное определение модели RoR ActiveRecord? - PullRequest
1 голос
/ 17 августа 2010

Простой вопрос, который меня озадачивал по поводу Rails:

Можно ли описать структуру модели из rb-файла модели?

Из того, что я понимаю, структура данных модели сохраняется в рамках миграции, и файл model.rb должен содержать только бизнес-логику.

Почему это так? Почему имеет смысл переносить базу данных с помощью задачи rake, чем извлекать ее из класса?

Ответы [ 2 ]

2 голосов
/ 17 августа 2010

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

Другие ORM (например, DataMapper) сохраняют схему в определении модели.Я думаю, что действительно удобно видеть атрибуты модели прямо здесь, но, к сожалению, не иметь истории структуры вашей базы данных.

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

1 голос
/ 18 августа 2010

Миграции не просто показывают состояние схемы базы данных.

Они определяют переходы из одного состояния в другое.

В комментарии к записи Кэма вы сказали, что наличие схемы в модели сделало бы то же самое, если бы у вас был источник модели, сохраненный в VCS, вы могли бы посмотреть предыдущие версии схемы.

Вот почему это не эквивалентно миграции:

Версия схемы 1
строка: имя
строка: пароль
строка: токен

Версия схемы 2
строка: имя пользователя
строка: отображаемое имя
строка: пароль
строка: токен

Итак, что я здесь сделал? Что случилось с «именем»? Я переименовал его в имя пользователя? Или, может быть, я переименовал его в displayname? Или я его полностью уронил?

Вы не знаете. Там нет никакого способа сказать. Вы видите только «до» и «после» схемы. Вы не видите переход.

Давайте вместо этого посмотрим, что я действительно сделал с этой миграцией:

class UpdateNameFields < ActiveRecord::Migration
  def self.up
    rename_column :users, :name, :username
    add_column :users, :displayname
    User.update_all("displayname = username")
  end

  def self.down
    remove_column :users, :displayname
    rename_column :users, :username, :name
  end
end

Видите ли, я использовал "имя" для имен пользователей. Но вы не сможете сказать это без миграции здесь. Кроме того, чтобы мой новый столбец отображаемых имен не был пустым во всех моих существующих записях, я добавил в него все существующие имена пользователей. Это позволяет мне аккуратно представить эту новую функцию - я могу использовать ее и знать, что существующие записи не будут просто видеть пустое поле.

Обратите внимание, что это тривиальный пример. Поскольку это было так тривиально, можно предположить, что это был один из нескольких возможных вариантов. Но если бы это был гораздо более сложный переход, вы бы просто не узнали.

Переходы из одной схемы в другую могут включать больше, чем просто добавление / удаление / переименование столбцов. Я привел небольшой пример выше в моем User.update_all. Любой код, который вам может понадобиться выполнить для переноса данных в новую схему, вы можете добавить в миграцию.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...