Прежде всего: я не согласен с ответом Джеффа. Это имеет смысл, когда ваше приложение мало и ваша логика проста. Я здесь, чтобы дать понять, как это может быть проблемой при создании и поддержании более крупного приложения. Я не рекомендую использовать этот подход при создании первого что-то маленькое, но иметь в виду в качестве альтернативного подхода:
вопрос здесь, является ли это значение по умолчанию в записях является бизнес-логика. Если это так, я был бы осторожен, чтобы поместить его в модель ORM. Поскольку поле ryw упоминает active, это звучит как бизнес-логика. Например. пользователь активен.
Почему я должен настороженно относиться к проблемам бизнеса в модели ORM?
It breaks SRP. Любой класс, наследующий от ActiveRecord :: Base, уже делает лот разных вещей, главным из которых является согласованность данных (валидации) и сохранение (сохранение). Полагая бизнес-логику, сколь бы малой она была, с AR :: Base прерывает SRP.
Это медленнее, чтобы протестировать. Если я хочу протестировать любую форму логики, происходящую в моей модели ORM, мои тесты должны инициализировать Rails для запуска. Это не будет большой проблемой в начале вашего приложения, но будет накапливаться до тех пор, пока ваши модульные тесты не займут много времени.
Это сломает SRP еще больше по линии, и конкретными способами. Скажите, что наш бизнес теперь требует от нас по электронной почте пользователей, когда Item становится активным? Теперь мы добавляем логику электронной почты в модель элемента ORM, основная задача которой - моделирование Item. Он не должен заботиться о логике электронной почты. Это случай деловых побочных эффектов. Они не принадлежат модели ORM.
Трудно разнообразить. Я видел зрелые приложения Rails с такими вещами, как база данных, поддерживаемая базой данных init_type: string, единственной целью которой является управление логикой инициализации. Это загрязняет базу данных, чтобы устранить структурную проблему. По-моему, есть лучшие способы.
The PORO образом: Хотя это немного больше коды, что позволяет сохранить ваш ORM модель и бизнес-логику отдельно. Этот код упрощен, но должно показать идею:
class SellableItemFactory
def self.new(attributes = {})
record = Item.new(attributes)
record.active = true if record.active.nil?
record
end
end
Тогда с этим на месте, так, чтобы создать новый элемент будет
SellableItemFactory.new
И мои тесты могут теперь просто проверить, что ItemFactory активирует элемент Item, если он не имеет значения. Нет необходимости инициализации Rails, без SRP. Когда инициализация элемента становится более продвинутой (например, установите поле состояния, тип по умолчанию и т. Д.), ItemFactory может добавить это. Если мы закончим с двумя типами дефолтов, мы можем создать новый BusinesCaseItemFactory для этого.
ПРИМЕЧАНИЕ. Также полезно использовать инъекцию зависимости, чтобы фабрика могла создавать много активных вещей, но я оставил ее для простоты. Вот оно: self.new (Klass = Item, атрибуты = {})
Похоже, вы ответили себе на вопрос, в двух разных вариантах :) – 2008-11-30 10:48:10
Обратите внимание, что «стандарт» Рубин идиома " self.status = ACTIVE, если self.status 'is' self.status || = ACTIVE ' – 2008-11-30 14:48:12