вторник, 22 июля 2008 г.

Как связана модель и таблица в БД?

Ну, давайте начнем. Модель - это класс, который предоставляет свои методы как интерфейс для работы с БД.

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

Нам не нужно создавать вручную ни таблицу, ни класс - рельса это сделает за нас. Достаточно для этого в консоли запустить генератор:
>ruby script\generate model User
в консоли генерируется список созданных файлов и папок:
> exists app/models/ - папка где хранятся все модели
> exists test/unit/ - папка для юнит-тестов
> exists test/fixtures/ - папка для фикстур
> create app/models/user.rb - файл модели
> create test/unit/user_test.rb - файл юнит-теста модели
> create test/fixtures/users.yml - файл где хрянтся фикстуры для модели
> create db/migrate - папка где хранятся миграции
> create db/migrate/001_create_users.rb - миграция для создания таблицы users

генератор создает нужные файли с шаблонным текстом для модели, функцональный тест, фикстуры. Нас пока будет интересовать только файл /app/model/user.rb - в котором и хранится наша модель. Он по-умолчанию содержит только обьявления класса(модели),
который наследуется от ActiveRecord - фреймворка для работы с БД

Генератор также создает в БД таблицу с именем users.

Модель всегда назывется в единственном числе, таблица получает свое имя путем приминения метода pluralize - метода, который возвращает входящий параметр преобразованый в множественное число, тоесть таблица users для модели User.

Для доступа к полю таблицы - используеться одноименный метод модели, например в таблице user есть поле name, то мы можем к нему обратиться как User.name

У вас возникает естественный вопрос: "Как модель знает какие поля есть у таблицы?"
Для того чтобы понять как ставиться в соответствие метод модели и поле базы - необходимо разобраться с миграциями, так как разгадка находиться в файле db/migrate/001_create_users.rb который создал наш генератор.

Подробно про о миграциях поговорим в следующей статье.


Немного терминологии:

Юнит-тест - это класс(тесты подробно рассмотрим позже) который привязывается к конкретной модели (имеет доступ ко всем ее методам), генерируется отдельно для каждой модели, манипулирует ее методами (может быть еще даже несуществующими), имитируя ее поведение заданое в спецификации. Основым инструментом для тестирования является утверждение(assert).

Утверждения могут быть разных типов, но общим для всех являеться сравнение уже известного параметра (согласно спецификации проекта) и параметра который возвращает модель в результате выполнения какого-либо метода.

Пример:утверждаем что количество юзеров в БД равняется 1:

def test_should_be_one_user_in_database
assert 1, User.count
end


Принято известный параметр указывать в утверждении слева. Результатом будет логичесое отрицание(тогда говорят про "падение теста", а имя метода укажет нам на вид ошибки - "в базе должен быть только один пользователь") или логическая "истина".

Таким образом: еще не реализовав модель, мы можем задать ее поведение (которое хочет заказчик). В тех местах где тест будет "падать" мы будем знать какая конкретно, и где, возникает ошибка. Если над проектом работает команда - то написание тестов просто необходимо, они тестируют все важные узлы системы, и программист сразу сможет увидеть что его код что-то нарушил в системе - и сразу все исправит.


Фикстуры: это файлы которые содержат записи для конкретных таблиц (в формате yml) . Реально, для разработки нужно 2 базы данных - для разработки и тестовая.

В БД разработки храняться реальные данные разрабатываемого проекта, которые программист тестирует у себя в браузере и вводит через формы.

В тестовой БД
хранятся данные на которых проганяются тесты, и эти данные как-раз и подгружаются каждый раз в БД из фикстур.

Существует две БД для того, чтобы тестовые данные были у всех разработчиков одинаковые и независили от того какие данные в проекта у каждого разработчика

2 комментария:

  1. Полезный блог, узнал немало нового, удачи тебе и спс за эти полезные статейки =)

    ОтветитьУдалить
  2. Спасиба, обязательно буду продолжать в том же духе. Ждите много интиресного

    ОтветитьУдалить