Спустя некоторое время с начала разработки вашего проекта, вы можете заметить, что у вас есть несоответствия между ограничениями в базе данных и валидациями в приложении. В данной статье, я объясняю как 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?
Попробуйте сами и поделитесь своим отзывом. Буду признателен за любой вклад!
Автор: new player