Спустя некоторое время с начала разработки вашего проекта, вы можете заметить, что у вас есть несоответствия между ограничениями в базе данных и валидациями в приложении. В данной статье, я объясняю как gem database_consistency поможет вам привести в порядок вашу базу данных.

Обсудим две возможные ситуации. Примеры кода написаны для ActiveRecord.

Первая ситуация


Допустим, у вас есть таблица, которая представлена следующим образом:

create_table :users do |t|
  t.string :name
end

и класс, объявленный как:

class User < ApplicationRecord
  validates :email, presence: true
end

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

create_table :users do |t|
  t.string :name, null: false
end

Вторая ситуация (обратная)


Допустим, у вас есть таблица, которая представлена следующим образом:

create_table :users do |t|
  t.string :name, null: false
end

и класс, объявленный как:

class User < ApplicationRecord
  validates :email
end

В этом случае, valid? вернет значение true для записей, которые не могут быть сохранены. Более того, попытка сохранить такую запись в базу данных исполнит от одного до нескольких SQL запросов и конечном счете вернет ошибку, откатив при этом всю транзакцию. Все эти манипуляции неэффективны и могут быть легко решены добавлением валидации presence: true. В большинстве случаев, вам следует добавить данную валидацию.

Передо мной встал вопрос: как найти все подобные случаи автоматически?
Представляю вам мой gem database_consistency. На данный момент, он обнаруживает большинство случаев. Как маленький бонус, он также подскажет ситуацию, где есть возможность сохранения записи с NULL значением в столбец с не нулевым ограничением.

Некоторые вопросы остаются открытыми:

  • Какие еще возможности реализовать?
  • Есть ли необходимость поддерживать другие ORM, например sequel?

Попробуйте сами и поделитесь своим отзывом. Буду признателен за любой вклад!

Комментарии (0)