У меня есть 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. Но это называется!
Извините за нелепую длину. Буду признателен за любую помощь, а также указатель на руководство по созданию этих вещей, которые я как-то упустил.