Rails: сохранение DRY с моделями ActiveRecord, которые имеют похожие сложные атрибуты - PullRequest
5 голосов
/ 20 мая 2010

Похоже, у него должен быть простой ответ, но после долгого времени в Google и ТАК я не могу его найти.Это может быть случай отсутствия правильных ключевых слов.

В моем приложении RoR у меня есть несколько моделей, которые имеют специфический тип строкового атрибута, который имеет специальную проверку и другие функции.Ближайший похожий пример, который я могу вспомнить, - это строка, представляющая URL.

Это приводит к большому дублированию в моделях (и еще большему дублированию в модульных тестах), но я не уверен, как сделать его более СУХИМЫМ.

Я могу придуматьнесколько возможных направлений ...

  1. создать плагин по аналогии с плагином validates_url_format_of, но это только сделает валидации DRY
  2. для этой специальной строки своей собственной моделью,но это кажется очень тяжелым решением
  3. создать класс ruby ​​для этой специальной строки, но как заставить ActiveRecord связать этот класс с атрибутом модели, который является строкой в ​​базе данных db

Номер 3 кажется наиболее разумным, но я не могу понять, как расширить ActiveRecord для обработки чего-либо, кроме базовых типов данных.Любые указатели?

Наконец, если есть способ сделать это, где в иерархии папок вы бы поместили новый класс, который не является моделью?

Большое спасибо.

ОБНОВЛЕНИЕ :

Одно из возможных решений с использованием предложения Мэтта о миксине, приведенного ниже (и с использованием примера URL).Обратите внимание, что это ближе к psuedocode, чем к реальному ruby ​​и предназначено для передачи принципа, а не совершенного синтаксиса.

Сначала создайте url mixin:

module Url
  def url_well_formed?
    [...]
  end

  def url_live?
    [...]
  end
end

И в *Модель 1033 *, включите этот модуль:

Class Site < ActiveRecord:Base
  include Url

  validate :url_well_formed?
end

И когда мне нужно проверить, что сайт по URL-адресу работает, выполните ...

if site.url_live?
  [...]
end

То, чего нетt решить, как сделать юнит-тесты сухими.Если у меня есть другая модель, скажем, Page, которая также использует миксин Url, ей все равно потребуется дубликат набора модульных тестов для URL.Конечно, я мог бы поместить их в помощник, но это кажется грязным.

Есть ли более фундаментальное решение, или это так хорошо, как оно получается?

Ответы [ 2 ]

6 голосов
/ 20 мая 2010

Создать абстрактную модель:

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
2 голосов
/ 20 мая 2010

Вы могли бы создать модуль со всеми распространенными методами и импортировать модуль? Google для mixins .

...