Как заставить работать пользовательский тип (Ruby) DataMapper? - PullRequest
2 голосов
/ 28 февраля 2012

У меня есть SchoolDay класс, который представляет школьный день: он может сообщить вам дату, семестр, семестр, неделю и день. Может генерировать строку типа «Sem1 13A Fri». Чтобы сохранить эти объекты в базе данных, я хочу, чтобы они сериализовались в виде строки.

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

module DataMapper
  class Property
    class SchoolDay < DataMapper::Property::String

      #load_as ::SchoolRecord::DomainObjects::SchoolDay
      # Commented out: the 'load_as' method is not found

      def load(value)
        # Take a string from the database and load it. We need a calendar!
        val = case value
        when ::String then calendar.schoolday(value)
        when ::SR::DO::SchoolDay then value
        else
          # fail
        end
      end

      def dump(value)
        # Store a SchoolDay value into the database as a string.
        case value
        when SR::DO::SchoolDay
          sd = value
          "Sem#{sd.semester} #{sd.weekstr} #{sd.day}"
        when ::String
          value
        else
          # fail
        end
      end

      def typecast(value)
        # I don't know what this is supposed to do -- that is, when and why it
        # is called -- but I am aping the behaviour of the Regexp custom type,
        # which, like this one, stores as a String and loads as something else.
        load(value)
      end

      # private methods calendar() and error_message() omitted
    end
  end
end

Этот код работает для чтения из базы данных (SQLite), но не для создания новых строк. Сообщение об ошибке:

Schoolday must be of type String

Код, который определяет ресурс DataMapper и пытается создать запись:

class LessonDescription
  include DataMapper::Resource
  property :id,          Serial
  property :schoolday,   SchoolDay  # "Sem1 3A Fri"
  property :class_label, String     # "10"
  property :period,      Integer    # (0..6), 0 being before school
  property :description, Text       # "Completed yesterday's worksheet. hw:(4-07)"
end

# ...

ld = LessonDescription.create(
  schoolday:    @schoolday,
  class_label:  @class_label,
  period:       @period,
  description:  description
)

Вот код типа преобразователя данных Regexp в библиотеке dm-types. Это так просто!

module DataMapper
  class Property
    class Regexp < String
      load_as ::Regexp                          # NOTE THIS LINE

      def load(value)
        ::Regexp.new(value) unless value.nil?
      end

      def dump(value)
        value.source unless value.nil?
      end

      def typecast(value)
        load(value)
      end

    end
  end
end

По какой-то причине я не могу использовать строку load_as в своем коде.

Подводя итог: я пытаюсь создать пользовательский тип, который переводит между SchoolDay (объект домена) и String (представление базы данных). Перевод прост, и я скопировал структуру кода в основном из типа DataMapper Regexp. Но когда я пытаюсь сохранить SchoolDay, он жалуется, что я не даю ему строку. К сожалению, я не могу использовать метод «load_as», который используют встроенные и пользовательские типы all , хотя у меня есть последняя версия. Я также не могу найти метод load_as, определенный где-либо в исходном коде для DataMapper. Но это называется!

Извините за нелепую длину. Буду признателен за любую помощь, а также указатель на руководство по созданию этих вещей, которые я как-то упустил.

1 Ответ

9 голосов
/ 29 февраля 2012

Кажется, что текущий код dm-types на github не попал ни в один официальный релиз - поэтому load_as не работает в вашем примере.Но попробуйте добавить этот метод:

module DataMapper
  class Property
    class SchoolDay < DataMapper::Property::String

      def custom?
        true
      end

    end
  end
end

Это работает здесь.

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