Это кажется, что должно иметь простой ответ, но после большого количества времени на Google и ТАКИМ ОБРАЗОМ, я не могу найти его. Это мог бы быть случай пропавших без вести правильных ключевых слов.
В моем приложении RoR у меня есть несколько моделей, которые совместно используют определенный вид строкового атрибута, который имеет специальную проверку и другую функциональность. Самым близким подобным примером, о котором я могу думать, является строка, которая представляет URL.
Это приводит к большому количеству дублирования в моделях (и еще больше дублирования в модульных тестах), но я не уверен, как сделать его большим количеством DRY.
Я могу думать о нескольких возможных направлениях...
Номер 3 кажется самым разумным, но я не могу выяснить, как расширить ActiveRecord для обработки чего-либо кроме базовых типов данных. Какие-либо указатели?
Наконец, если существует способ сделать это, куда в иерархии папок Вы поместили бы новый класс, который не является моделью?
Большое спасибо.
ОБНОВЛЕНИЕ:
Одно потенциальное решение с помощью смешивания Matt предложения ниже (и использование примера URL). Отметьте, это ближе к psuedocode, чем реальный рубин и предназначается для передачи принципа, а не идеального синтаксиса.
Во-первых, создайте a url
смешивание:
module Url
def url_well_formed?
[...]
end
def url_live?
[...]
end
end
И в a Site
модель, включайте этот модуль:
Class Site < ActiveRecord:Base
include Url
validate :url_well_formed?
end
И когда я должен проверить, что сайт в URL жив, сделать...
if site.url_live?
[...]
end
Вещь, которую это не решает, состоит в том, как сделать модульные тесты DRY. Если я имею другую модель, говорю Page
, это также использует Url
смешивание, этому все еще будет нужен дублирующийся набор модульных тестов на URL. Конечно, я мог поместить их в помощника, но это кажется грязным.
Существует ли более фундаментальное решение, или действительно ли это столь хорошо, как это добирается?
Вы можете создать модуль со всеми распространенными методами и импортировать его? Google для миксинов .
Создайте абстрактную модель:
class CommonBase < ActiveRecord::Base
self.abstract_class = true # makes the model abstract
validate_format_of :url_field, :with => /.../
end
Наследуйте свои модели от абстрактной модели:
class User < CommonBase
end
class Post < CommonBase
end