Ruby on Rails: лучше проверить в модели или базе данных? - PullRequest
39 голосов
/ 03 марта 2010

Как правило, лучше (и почему) проверять атрибуты в модели или в определении базы данных?

Для (тривиального) примера:

В пользовательской модели:

validates_presence_of :name

против миграции:

t.string :name, :null => false 

С одной стороны, включение его в базу данных кажется большей гарантией от любого проникновения плохих данных. С другой стороны, включение его в модель делает вещи более прозрачными и понятными, группируя их в код с остальной частью проверок. Я также подумал о том, чтобы сделать и то, и другое, но это кажется и СУХИМЫМ, и менее ремонтопригодным.

Ответы [ 6 ]

46 голосов
/ 03 марта 2010

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

11 голосов
/ 03 марта 2010

А также

validates_presence_of :name

не то же самое, что

t.string :name, :null => false 

Если вы просто установили столбец NOT NULL в своей БД, вы все равно можете вставить пустое значение (""). Если вы используете модель validates_presence_of - вы не можете.

4 голосов
/ 03 марта 2010

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

2 голосов
/ 03 марта 2010

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

1 голос
/ 29 января 2015

Я бы рекомендовал проект Migration Validators (https://rubygems.org/gems/mv-core), чтобы определить валидацию на уровне БД, а затем прозрачно продвинуть ее в модель ActiveRecord.

Пример:

в миграции:

def change
  create_table :posts do |t|
    t.string :title, length: 1..30
  end 
end

в вашей модели:

class Post < ActiveRecord::Base
  enforce_migration_validations
end

В результате у вас будет двухуровневая проверка данных. Первый будет реализован в db (как условие в триггере проверочного ограничения), а второй - как проверка ActiveModel в вашей модели.

0 голосов
/ 03 марта 2010

Зависит от вашего дизайна приложения, Если у вас есть приложение малого или среднего размера, вы можете сделать это как в модели, так и в модели, Но если у вас большое приложение, вероятно, оно ориентировано на службы или находится в нескольких слоях, тогда необходимо выполнить базовую проверку, т. Е. Обязательную / обнуляемую, минимальную / максимальную длину и т. Д. В базе данных, а также более строгие шаблоны или бизнес-правила в модели.

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